js
是单线程语言,对于异步操作只能先把它放在一边,按照某种规则按先后顺序放进一个容器(其实就是存入宏观任务和微观任务队列中),先处理同步任务,再处理异步任务。异步任务分为 [ 宏观任务队列、微观任务队列 ]
按照规定,能发起宏观任务的方法有:
script(整体代码)
、setTimeout
、setInterval
、I/O
、UI
交互事件、postMessage
、MessageChannel
、setImmediate
(Node.js
环境);
微观任务的方法有:
Promise.then
、MutaionObserver
、process.nextTick
(Node.js
环境),async/await
实际上是promise+generator
的语法糖,也就是promise
,也就是微观任务;
同步任务结束后,先处理微观任务后处理宏观任务
// 先来看下下面这段代码
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0)
async1();
new Promise(function(resolve) {
console.log('promise1');
resolve();
}).then(function() {
console.log('promise2');
});
console.log('script end');
/*执行结果
script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout
*/
先大体看下代码:
从上往下看,先走同步队列,再走异步队列(包含微观任务队列和宏观任务队列)。
同步队列:script start
→ async1
start
→ async2
→ promise1
→ script end
异步队列:包括微观任务和宏观任务。
微观任务:async1 end
→ promise2
宏观任务: setTimeout
→
- 同步任务:
script start → async1 start → async2 → promise1 → script end
; - 微观任务:
async1 end → promise2 →
; - 宏观任务:
setTimeout →
Q.E.D.