# ❓setTimeout、Promise、Async/Await 的区别?
看题,这应该是考察 javascript
宏任务队列/微任务队列以及事件循环机制的问题。
我是这么理解的:
setTimeout 本身是一个宏任务
// 代码的执行顺序,就跟打印的号码顺序一样 // 一次只能执行一个宏任务 // 遇到setTimeout 宏任务 推入宏任务队列 // 继续执行 执行完毕发现没有微任务 执行下一个宏任务 // 以此类推 这也是 js 事件循环机制 console.log(1); setTimeout(() => { console.log("setTimeout 3"); }); console.log(2);
1
2
3
4
5
6
7
8
9
10Promise 自身是宏任务 但回调是微任务
// 也是一道经典的面试题目 // 也是一样 执行顺序就是打印的号码 // 第一次宏任务开始执行 console.log(1); new Promise((resolve, reject) => { console.log(2); resolve(); console.log(3); }).then(() => { // 第一次宏任务 附带的微任务 // 所以要在第一次宏任务走完的时候要执行掉 console.log(5); }); // 第二次宏任务注册 // 推入宏任务队列 setTimeout(() => { console.log(6); }); console.log(4);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20Async/Await 关键字:
async
await
本质上还是基于promise
的一些封装// 被添加入下一次宏任务队列 setTimeout(_ => console.log(6)); async function test() { console.log(1); // 我的理解是 // 遇到 await 先执行其同步内容 // 让出执行线程(跳出当前任务)同时推入微任务队列 继续往下执行 // 执行完之后 回来继续执行 await new Promise((resolve, reject) => { console.log(2); resolve(); }).then(_ => console.log(4)); // 这里 5 没有进入微任务队列 只不是相当于被挂起了 console.log(5); } test(); test(); console.log(3); // 如果执行一次 test 函数 结果 => 123456 // 如果执行两次 test 函数 结果 => 1212344556
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 宏任务有哪些呢?
# | 浏览器 | node |
---|---|---|
I/O | ✅ | ✅ |
setTimeout | ✅ | ✅ |
setInterval | ✅ | ✅ |
setImmediate | ❌ | ✅ |
requestAnimationFrame | ✅ | ❌ |
# 微任务有哪些呢?
# | 浏览器 | node |
---|---|---|
process.nextTick | ❌ | ✅ |
MutationObserver | ✅ | ❌ |
Promise.then catch finally | ✅ | ✅ |