Javascript的运行机制

38次阅读

共计 1222 个字符,预计需要花费 4 分钟才能阅读完成。

概述

JS 是单线程,但是主线程完全可以不管 IO 设备,挂起处于等待中的任务,先运行排在后面的任务。等到 IO 设备返回了结果,再回过头,把挂起的任务继续执行下去。

所有任务可以分成两种,一种是同步任务,另一种是异步任务

JavaScript 的运行机制如下

1. 所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)
2. 主线程之外,还存在一个 ” 任务队列 ”(task queue)。只要异步任务有了运行结果,就在 ” 任务队列 ” 之中放置一个事件。
3. 一旦 ” 执行栈 ” 中的所有同步任务执行完毕,系统就会读取 ” 任务队列 ”,看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
4. 主线程不断重复上面的第三步。

“任务队列”中的事件,先进先出

IO 设备的事件
用户产生的事件(比如鼠标点击、页面滚动等等)
只要指定过回调函数,这些事件发生时就会进入”任务队列”,放置定时事件

Event Loop

主线程从”任务队列”中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为 Event Loop(事件循环)

定时器功能

由于存在后文提到的”定时器”功能,主线程首先要检查一下执行时间,某些事件只有到了规定的时间,才能返回主线程。

setTimeout(fn,0)的含义是,指定某个任务在主线程最早可得的空闲时间执行,也就是说,尽可能早得执行。它在”任务队列”的尾部添加一个事件,因此要等到同步任务和”任务队列”现有的事件都处理完,才会得到执行。

Node.js 也是单线程的 Event Loop,但是它的运行机制不同于浏览器环境。


Node.js 的运行机制如下。
1.V8 引擎解析 JavaScript 脚本。
2. 解析后的代码,调用 Node API。
3.libuv 库负责 Node API 的执行。它将不同的任务分配给不同的线程,形成一个 Event Loop(事件循环),以异步的方式将任务的执行结果返回给 V8 引擎。
4.V8 引擎再将结果返回给用户。

除了 setTimeout 和 setInterval 这两个方法,Node.js 还提供了另外两个与”任务队列”有关的方法:process.nextTick 和 setImmediate。

process.nextTick 方法可以在当前”执行栈”的尾部—- 下一次 Event Loop(主线程读取”任务队列”)之前—- 触发回调函数。它指定的任务总是发生在所有异步任务之前。

setImmediate 方法则是在当前”任务队列”的尾部添加事件,也就是说,它指定的任务总是在下一次 Event Loop 时执行,这与 setTimeout(fn, 0)很像。

process.nextTick 和 setImmediate 的一个重要区别:多个 process.nextTick 语句总是在当前”执行栈”一次执行完,多个 setImmediate 可能则需要多次 loop 才能执行完



这题会先把 promise2 加到微任务中,然后再把 async1 end 加到微任务中


正文完
 0