nodejs 中的异步执行顺序
前段时间给朋友讲解 Node.js 的异步执行问题,今天翻到当时的代码和解释,做个记录
什么是事件循环?
在讲解具体代码之前,我们先了解一下什么是事件循环(Event Loop)。
可以把事件循环想象成一个游乐场的管理员,他管理着两个队伍:
- 宏任务队列(Macrotask Queue):就像游乐场里的大型项目队伍,比如过山车、摩天轮等,需要较长时间体验
- 微任务队列(Microtask Queue):就像游乐场里的小型项目队伍,比如旋转木马、碰碰车等,可以快速体验
事件循环的工作方式是:
- 检查微任务队列,把所有的小项目(微任务)都玩一遍
- 然后从大项目(宏任务)队伍中选择第一个项目去体验
- 体验完这个大项目后,再次检查并清空所有小项目队伍
- 重复这个过程,直到所有项目都体验完毕
代码示例
让我们通过一个具体例子来理解这个过程:
1 | |
执行过程详解
第一阶段:同步代码执行
首先执行所有同步代码,按顺序注册宏任务和微任务:
第 27 行,注册 hello 宏任务
1 | |
第 33 行注册 world 宏任务
1 | |
第 37 行调用 Promise,输出 “start 1”,并注册微任务 then1.1
1 | |
第 38 行调用 Promise,输出 “start 2”,并注册微任务 then2.1
1 | |
同步代码执行完毕,接下来进入事件循环阶段。
第二阶段:执行微任务队列
执行所有微任务,按顺序处理:
执行 then1.1 微任务
1
2
3
4控制台输出:p-1
注册宏任务:__inner 1__
宏任务队列:[__hello__,__world__,__inner 1__]
微任务队列:[]执行 then2.1 微任务
1
2
3
4控制台输出:p-2
注册宏任务:__inner 2__
宏任务队列:[__hello__,__world__,__inner 1__,__inner 2__]
微任务队列:[then1.2] // then1.1 执行完后注册的 then1.2执行 then1.2 微任务
1
2
3控制台输出:p-debug
宏任务队列:[__hello__,__world__,__inner 1__,__inner 2__]
微任务队列:[then2.2] // then2.1 执行完后注册的 then2.2执行 then2.2 微任务
1
2
3控制台输出:p-debug
宏任务队列:[__hello__,__world__,__inner 1__,__inner 2__]
微任务队列:[]
微任务队列清空,准备执行第一个宏任务。
第三阶段:执行宏任务和相应的微任务
执行 hello 宏任务
1
2
3
4
5
6控制台输出:hello
调用 f(3):
控制台输出:start 3
注册微任务:then3.1
宏任务队列:[__world__,__inner 1__,__inner 2__]
微任务队列:[then3.1]执行 then3.1 微任务
1
2
3
4控制台输出:p-3
注册宏任务:__inner 3__
宏任务队列:[__world__,__inner 1__,__inner 2__,__inner 3__]
微任务队列:[]执行 then3.1 后续的微任务
1
2
3控制台输出:p-debug
宏任务队列:[__world__,__inner 1__,__inner 2__,__inner 3__]
微任务队列:[]
第四阶段:依次执行剩余宏任务
执行 world 宏任务
1
2
3控制台输出:world
宏任务队列:[__inner 1__,__inner 2__,__inner 3__]
微任务队列:[]执行 inner 1 宏任务
1
2
3控制台输出:inner 1
宏任务队列:[__inner 2__,__inner 3__]
微任务队列:[]执行 inner 2 宏任务
1
2
3控制台输出:inner 2
宏任务队列:[__inner 3__]
微任务队列:[]执行 inner 3 宏任务
1
2
3控制台输出:inner 3
宏任务队列:[]
微任务队列:[]
至此,宏任务和微任务队列全部清空,程序执行完毕。
nodejs 中的异步执行顺序
https://bubao.github.io/posts/f05aaded.html