一、为什么 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语言的设计者意识到