什么是事件循环?
JavaScript 单线程,通过事件循环处理异步任务。
执行栈
函数调用形成栈。
任务队列
异步任务放入队列。
宏任务 vs 微任务
- 宏任务:setTimeout, setInterval, I/O
- 微任务:Promise, MutationObserver
执行顺序
- 执行同步代码
- 执行所有微任务
- 执行一个宏任务
- 重复
例子
1 | console.log('start') |
总结
理解事件循环对写异步代码很重要。微任务优先于宏任务。
Node 事件循环分阶段
Node 事件循环有多个阶段,利用 libuv 实现:
- timers 阶段:执行计时器回调(
setTimeout、setInterval) - pending callbacks:处理上一轮循环遗留的 I/O 回调
- idle, prepare:内部
- poll 阶段:等待新的 I/O 事件
- check 阶段:执行
setImmediate回调 - close callbacks:执行关闭回调
示例:
1 | fs.readFile('file', () => { |
高级话题
为什么 Promise.then 是微任务?
标准指定所有 .then 回调加入微任务队列,以确保在当前宏任务结束后立即执行,这样可以保证程序逻辑的一致性。
MutationObserver 与微任务
MutationObserver 也会插入微任务,可用来观察 DOMMutationObserver 也会插入微任务,可用来观察 DevTooMutationObserver 也会插的 MutationObserver 也会插入微任务,可用来观�或MutationObserver 也会插入微任务,可用来观察 DOMMutationO长MutationObserver也会插入微任务,可用来观察setImMutationObserver 也�out(…,0) 在 Node 中避免在 timers �MutationObserver 也会插入微任务,� 提高异步代码可读性
常见错误
- 在微任务中�- 在微任务中�- 在
�-------------------extTick-------------------extTick---------------的-------------------extTick` -------------| No—|
|------|--------|------|
| 微任务 | Promise、MutationObserver | Promise|��pr| 微任务 | P|
|||||||||||||||||||||||||||||||||||||||||||| t|||||||||||||||||||||||||||||||||||||||||||| t|||||||||||||||||||||||||||||||||||||||||||| t|||||||||||||||||||||||||||||||||||||||||||| t|||||||||||- 参�|||||||||||||||||||||||||||||||�
附加事件循环行 1
附加事件循环行 2
附加事件循环行 3
附加事件循环行 4
附加事件循环行 5
附加事件循环行 6
附加事件循环行 7
附加事件循环行 8
附加事件循环行 9
附加事件循环行 10
附加事件循环行 11
附加事件循环行 12
附加事件循环行 13
附加事件循环行 14
附加事件循环行 15
附加事件循环行 16
附加事件循环行 17
附加事件循环行 18
附加事件循环行 19
附加事件循环行 20
附加事件循环行 21
附加事件循环行 22
附加事件循环行 23
附加事件循环行 24
附加事件循环行 25
附加事件循环行 26
附加事件循环行 27
附加事件循环行 28
附加事件循环行 29
附加事件循环行 30
附加事件循环行 31
附加事件循环行 32
附加事件循环行 33
附加事件循环行 34
附加事件循环行 35
附加事件循环行 36
附加事件循环行 37
附加事件循环行 38
附加事件循环行 39
附加事件循环行 40
附加事件循环行 41
附加事件循环行 42
附加事件循环行 43
附加事件循环行 44
附加事件循环行 45
附加事件循环行 46
附加事件循环行 47
附加事件循环行 48
附加事件循环行 49
附加事件循环行 50
附加事件循环行 51
附加事件循环行 52
附加事件循环行 53
附加事件循环行 54
附加事件循环行 55
附加事件循环行 56
附加事件循环行 57
附加事件循环行 58
附加事件循环行 59
附加事件循环行 60