事件循环模型

916 阅读2分钟

js是单线程执行的,是因为保证只能由一个线程去操作DOM。

模型:

1、执行栈 stack:

execution stack
所有的代码都是在此空间中执行的。

2、堆 heap

对象被分配在堆中,堆是一个用来表示一大块(通常是非结构化的)内存区域的计算机术语。

3、队列callback queue

一个 JavaScript 运行时包含了一个待处理消息的消息队列。每一个消息都关联着一个用以处理这个消息的回调函数。

4、事件循环 event loop:

  • 执行初始化代码, 将事件回调函数交给对应模块管理
  • 当事件发生时, 管理模块会将回调函数及其数据添加到回调列队
  • 只有当初始化代码执行完后(可能要一定时间), 才会遍历读取回调队列中的回调函数执行

也可以按照如下去理解:

事件循环:

     运行时会从最先进入队列的消息开始处理队列中的消息。被处理的消息会被移出队列,并作为输入参数来调用与之关联的函数。正如前面所提到的,调用一个函数总是会为其创造一个新的栈帧。

函数的处理会一直进行到执行栈再次为空为止;然后事件循环将会处理队列中的下一个消息。

之所以称之为 事件循环,是因为它经常按照类似如下的方式来被实现:

while (queue.waitForMessage()) {
  queue.processNextMessage();
}

任务队列

    所有的任务可以分为同步任务和异步任务,同步任务,顾名思义,就是立即执行的任务,同步任务一般会直接进入到主线程中执行;而异步任务,就是异步执行的任务,比如ajax网络请求,setTimeout定时函数等都属于异步任务,异步任务会通过任务队列(Event Queue)的机制来进行协调。

事件循环 event loop:

  同步和异步任务分别进入不同的执行环境,同步的进入主线程,即主执行栈,异步的进入Event Queue。主线程内的任务执行完毕为空,会去Event Queue读取对应的任务,推入主线程执行。

浏览器内核

browser core
js引擎模块(在主线程处理)
其它模块(在主/分线程处理)

定时器任务

定时器任务不能保证在设定的时间执行, 会有一点延迟。