一、为什么 JavaScript 单线程

假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?

为了避免复杂性, JS 采用了单线程的模式,也就是一次只能执行一个程序

二、事件机制(观察者模式)

其实 JS 是一直有两个线程在跑,只不过一个负责跑我们写的主程序,另一个线程负责事件任务的监听并在需要响应的时候发起通知。下面请看图一:

由图一我们很直观的看出了 JS 分为了两个线程,主线程中的主程序部分,就是非常规则的按照单线程的方式一行一行的去运行我们编写的非事件函数里的 JS 代码。

而在主程序的黄色部分,则是碰到了需要注册的事件代码,图中以 onclick 为例子,这时主程序就会在事件监听表里添加一条 onclick 的监听。这时候,次线程就开始去监听事件的行为了。当次线程监听到这个事件所绑定的元素被点击后,就会发出通知(在事件任务队列里插入一条需要想要的事件)。之后次程序就一直做这个事。

主线程中,等到主程序执行完毕后,系统就会读取"任务队列",如果发现有事件,则执行。否则继续读取"任务队列"直到下一个事件出现。

ps:图中事件函数部分,绿色为等待事件任务出现,红色部分为正在执行的事件函数。

主线程和次线程的流程:

主线程

  1. 主程序的执行
  2. 系统就会读取"任务队列"
  3. 如果发现有事件出现,则执行,否则重复2
  4. 程序结束或者事件监测注册表为空的时候退出

ps:只要主线程空了,就会去读取"任务队列",这就是JavaScript的运行机制。这个过程会不断重复。

次线程

  1. 根据事件监测注册表的内容进行监听
  2. 发现事件监测注册表的内容得到结果,则发起通知(在事件任务队列里插入一条需要想要的事件)
  3. 重复1、2

二、为什么这样的 JS 高效率

单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。

如果排队是因为计算量大,CPU忙不过来,倒也算了,但是很多时候CPU是闲着的,因为IO设备(输入输出设备)很慢(比如Ajax操作从网络读取数据),不得不等着结果出来,再往下执行。

JavaScript语言的设计者意识到,这时主线程完全可以不管IO设备,挂起处于等待中的任务,先运行排在后面的任务。等到IO设备返回了结果,再回过头,把挂起的任务继续执行下去。

JS 运行时 CPU 和各个硬件资源都被充分的利用了。而一门语言效率是否高,主要就是看对资源怎么合理分配的,因为计算机的总计算能力是有限,只要让每个硬件减少等待时间,充分利用好资源,就可以高效率,而 JS 就是这么一门语言。

而有些人则会疑问,为什么 JAVA 语言运行效率比这个高的,这就得归结到,JS 是一门解释语言,没有编译等,所以执行的过程需要翻译等,这些都是需要系统的开销的。而解释效率是否高等,就要看 JS 引擎的解释效率了。

参考文献:

一张图看懂 JS 的事件机制的更多相关文章

  1. 一张图看懂 JS 原型链

    JS 原型链,画了张图,终于理清楚各种关系有木有 写在最后: __proto__是每个对象都有的一个属性,而prototype是函数才会有的属性!!! function Person() { } 是函 ...

  2. 一张图看懂ANSYS17.0 流体 新功能与改进

    一张图看懂ANSYS17.0 流体 新功能与改进   提交 我的留言 加载中 已留言   一张图看懂ANSYS17.0 流体 新功能与改进 原创2016-02-03ANSYS模拟在线模拟在线 模拟在线 ...

  3. 一张图看懂开源许可协议,开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别

    一张图看懂开源许可协议,开源许可证GPL.BSD.MIT.Mozilla.Apache和LGPL的区别 首先借用有心人士的一张相当直观清晰的图来划分各种协议:开源许可证GPL.BSD.MIT.Mozi ...

  4. FUNMVP:几张图看懂区块链技术到底是什么?(转载)

    几张图看懂区块链技术到底是什么? 本文转载自:http://www.cnblogs.com/behindman/p/8873191.html “区块链”的概念可以说是异常火爆,好像互联网金融峰会上没人 ...

  5. 4张图看懂delphi 10生成ipa和在iPhone虚拟器上调试(教程)

    4张图看懂delphi 10生成ipa和在iPhone虚拟器上调试(教程) (2016-02-01 03:21:06) 转载▼ 标签: delphi ios delphi10 教程 编程 分类: 编程 ...

  6. 一张图看懂css的position里的relative和absolute的区别

    position有以下属性:static.inherit.fixed.absolute.relative前三个好理解好区分:static:是默认状态,没有定位,元素出现在正常的流中(忽略 top, b ...

  7. [转帖]两张图看懂GDT、GDTR、LDT、LDTR的关系

    两张图看懂GDT.GDTR.LDT.LDTR的关系 2018-06-09 18:13:53 Six_666A 阅读数 2044更多 分类专栏: 深入理解linux内核   转自:http://ju.o ...

  8. 一张图看懂Function和Object的关系及简述instanceof运算符

    我在写一篇图解prototype和__proto__的区别时,搜资料搜到了一个有意思的现象,下面这两个运算返回的结果是一样的: Function instanceof Object;//true Ob ...

  9. Nodejs学习笔记(三)——一张图看懂Nodejs建站

    前言:一条线,竖着放,如果做不到精进至深,那就旋转90°,至少也图个幅度宽广. 通俗解释上面的胡言乱语:还没学会爬,就学起走了?! 继上篇<Nodejs学习笔记(二)——Eclipse中运行调试 ...

随机推荐

  1. Java编程思想非主流知识点

    1. Java中的多态性理解(注意与C++区分) Java中除了static方法和final方法(private方法本质上属于final方法,因为不能被子类访问)之外,其它所有的方法都是动态绑定,这意 ...

  2. javah编译class文件找不到android.app.Activity的类文件

    在android工程的根目录使用javah生成jni 头文件时候,报找不到android.app.Activity的类文件错误. 无法访问android.app.Activity是说明没有引入andr ...

  3. 虔诚的墓主人(bzoj 1227)

    Description 小W 是一片新造公墓的管理人.公墓可以看成一块N×M 的矩形,矩形的每个格点,要么种着一棵常青树,要么是一块还没有归属的墓地.当地的居民都是非常虔诚的基督徒,他们愿意提前为自己 ...

  4. OC-Objection 学习笔记之一:简单的开始

    Objection 统一管理对象的引用问题,我想这就是这种技术的意义吧. 废话不说,咱们直接上步骤吧: 1:协议 我们的意识里要知道,一切围绕协议来进行. 下面的协议是一个视图的协议,该协议简单到不能 ...

  5. centos 6.5下编译安装、配置高性能服务器Nginx

    1.nginx是什么? Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,由俄罗斯的程序设计师Igor Sysoev所开发,其特点是占有内存少,并发能力 ...

  6. C#子窗口与父窗口交互(使用委托和事件)

    目标:在子窗口Form2上单击按钮时向Form1传递一组自定义参数,并显示在父窗口Form1上. 方法:有很多方法,这里只介绍委托和事件的实现方式. 思路:Form2中定义事件,Form1创建Form ...

  7. Java获取异常堆栈信息

    方法一: public static String getStackTrace(Throwable t) { StringWriter sw = new StringWriter(); PrintWr ...

  8. JWPlayer使用指南

    http://support.jwplayer.com/customer/portal/articles/1499103-quickstart-reference <div id="m ...

  9. MYBATIS 无效的列类型: 1111

    查询的时候竟然也会报错,如果参数是数字,需要加上jdbcType 在xml中加上 t.chart_id = #{chartId,jdbcType=DECIMAL}

  10. Linux笔记(三) - 文件搜素

    (1)文件搜索:find-name  根据文件名, *匹配任意字符 ,?单个字符-iname  根据文件名, 不区分大小写-size 根据文件大小查找 (+ 大于 -小于)(-a并且 -o或者)-us ...