nodejs事件循环
2018-10-26 本文已影响7人
88b61f4ab233
1. 只有一个主线程,node
开始执行脚本时,会先进事件循环初始化(同步任务,发出异步请求,规划定时器生效时间,执行promise.nextTick
等),这时事件循环还未开始。
nodejs运行机制:
- V8引擎解析
js
脚本 - 解析后的代码调用
Node API
- 库负责
Node API
的执行,它将不同的任务分配给不同的线程,形成一个Event Loop
,以异步的方式将任务的执行结果返回给V8引擎 - V8引擎再将结果返回给用户
2.nodejs每一轮事件循环的六个阶段(事件循环会无限次执行,直到异步任务的回调函数队列清空才会停止执行):
-
timers
(处理setTimeout
和setInterval
的回调函数) -
I/O callbacks
(除了setTimeout
、setInterval
、setImmediate
、用于关闭请求的回调函数) -
idle
,prepare
(libuv
内部使用) -
poll
(等待还未返回的I/O
事件) -
check
(setImmediate
) -
close callbacks
(执行关闭请求的回调,如socket.on('close', ...)
)
3. setTimeout
和setImmediate
:
由于setTimeout
第二个参数默认为0,但是加上node
做不到真正的0ms,最少也需要1s;所以实际执行进入事件循环后,如果没到1ms,那么timers
阶段就会跳过进入check
阶段,所以执行顺序不确定。
4. 异步任务分两种:
本轮循环:promise.nextTick
、promise
的回调函数
次轮循环:setTimeout
、setInteval
、setImmediate
的回调函数
- 多个
process.nextTick
语句总是在当前"执行栈"一次执行完,多个setImmediate
可能则需要多次loop才能执行完;
6. 为什么process.nextTick
永远大于 promise.then
?因为Node
中,_tickCallback
在每一次执行完TaskQueue
中的一个任务后被调用,而这个_tickCallback
中实质上干了两件事:
-
nextTickQueue
中所有任务执行掉(长度最大1e4,Node版本v6.9.1) - 第一步执行完后执行
_runMicrotasks
函数,执行microtask
中的部分(promise.then
注册的回调)