概念:
JavaScript 从 script 开始读取,然后不断循环,从 “任务队列” 中读取执行事件的过程,就是 事件循环(Event Loop)
Event Loop 执行过程:
- 一开始整个脚本 script 作为一个宏任务执行
- 执行过程中,同步代码 直接执行,宏任务 进入宏任务队列,微任务 进入微任务队列。
- 当前宏任务执行完出队,检查微任务列表,有则依次执行,直到全部执行完毕。
- 执行浏览器 UI 线程的渲染工作。
- 检查是否有 Web Worker 任务,有则执行。
- 执行完本轮的宏任务,回到步骤 2,依次循环,直到宏任务和微任务队列为空
事件循环中的异步队列有两种:宏任务队列(MacroTask)和 微任务队列(MicroTask)。
宏任务队列可以有多个,微任务队列只有一个。
宏任务 包括:
- script
- setTimeout
- setInterval
- setImmediate
- I/O
- UI rendering
微任务 包括: - MutationObserver
- Promise.then()/catch()
- 以 Promise 为基础开发的其他技术,例如 fetch API
- V8 的垃圾回收过程
- Node 独有的 process.nextTick
题目1:
console.log("script start");
setTimeout(function() {
console.log("setTimeout---0");
}, 0);
setTimeout(function() {
console.log("setTimeout---200");
setTimeout(function() {
console.log("inner-setTimeout---0");
});
Promise.resolve().then(function() {
console.log("promise5");
});
}, 200);
Promise.resolve()
.then(function() {
console.log("promise1");
})
.then(function() {
console.log("promise2");
});
Promise.resolve().then(function() {
console.log("promise3");
});
console.log("script end");
script start
script end
promise1
promise3
Promise2
setTimeout---0
setTimeout—200
promise5
inner-setTimeout—0
题目2:
console.log(1);
setTimeout(() => {
console.log(2);
new Promise((resolve) => {
console.log(3);
}).then(() => {
console.log(4);
});
}, 200);
new Promise((resolve) => {
console.log(5);
resolve();
}).then(() => {
console.log(6);
});
setTimeout(() => {
console.log(7);
}, 0);
setTimeout(() => {
console.log(8);
new Promise(function (resolve) {
console.log(9);
resolve();
}).then(() => {
console.log(10);
});
}, 100);
new Promise(function (resolve) {
console.log(11);
resolve();
}).then(() => {
console.log(12);
});
console.log(13);
1
5
11
13
6
12
7
8
9
10
2
3