1蜜笤、JS是單線(xiàn)程語(yǔ)言,包括同步任務(wù)盐碱、異步任務(wù)把兔,異步任務(wù)又包括宏觀任務(wù)和微觀任務(wù)
2、執(zhí)行順序:同步任務(wù)——>微觀任務(wù)——>宏觀任務(wù)
3瓮顽、宏觀任務(wù)的方法有:script(整體代碼)县好、setTimeout、setInterval暖混、I/O缕贡、UI交互事件、postMessage拣播、MessageChannel晾咪、setImmediate(Node.js 環(huán)境)
4、微觀任務(wù)的方法有:Promise.then贮配、MutaionObserver谍倦、process.nextTick(Node.js 環(huán)境),async/await實(shí)際上是promise+generator的語(yǔ)法糖牧嫉,也就是promise剂跟,也就是微觀任務(wù)
1. setTimeout
console.log('script start') //1. 打印 script start
setTimeout(function(){
console.log('settimeout') // 4. 打印 settimeout
}) // 2. 調(diào)用 setTimeout 函數(shù),并定義其完成后執(zhí)行的回調(diào)函數(shù)
console.log('script end') //3. 打印 script start
// 輸出順序:script start->script end->settimeout
2. Promise
console.log('script start')
let promise1 = new Promise(function (resolve) {
console.log('promise1')
resolve()
console.log('promise1 end')
}).then(function () {
console.log('promise2')
})
setTimeout(function(){
console.log('settimeout')
})
console.log('script end')
// 輸出順序: script start->promise1->promise1 end->script end->promise2->settimeout
3. async/await
async function async1(){
console.log('async1 start');
await async2();
console.log('async1 end')
}
async function async2(){
console.log('async2')
}
console.log('script start');
async1();
console.log('script end')
// 輸出順序:script start->async1 start->async2->script end->async1 end
執(zhí)行先后順序 setTimeout酣藻、Promise曹洽、Async/Await 對(duì)比
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('start');
setTimeout(() => {
console.log('setTimeout');
}, 0);
async1();
new Promise(resolve => {
console.log('promise1');
resolve();
}).then(() => {
console.log('promise2');
})
console.log('end');
運(yùn)行結(jié)果
start
async1 start
async2
promise1
end
promise2
async1 end
setTimeout
調(diào)用順序問(wèn)題解析:
async 會(huì)定義一個(gè)返回 AsyncFunction 對(duì)象的異步函數(shù)。即以 async 聲明的函數(shù)辽剧,會(huì)隱式地返回一個(gè) Promise 對(duì)象送淆。當(dāng)這個(gè) async 函數(shù)返回一個(gè)值時(shí),Promise 的 resolve 方法會(huì)負(fù)責(zé)傳遞這個(gè)值怕轿;當(dāng) async 函數(shù)拋出異常時(shí)偷崩,Promise 的 reject 方法也會(huì)傳遞這個(gè)異常值辟拷。
await 操作符用于等待一個(gè) Promise 對(duì)象。它返回 Promise 對(duì)象的處理結(jié)果阐斜。如果等待的不是 Promise 對(duì)象衫冻,則返回該值本身。
注意:
await 只能在異步函數(shù) async function 中使用谒出。
如果你希望并行等待兩個(gè)或者是更多的 Promise 對(duì)象隅俘,你必須使用Promise.then,而不是await笤喳。
隊(duì)列任務(wù)優(yōu)先級(jí):promise.Trick() > promise的回調(diào) > setTimeout > setImmediate
因此上述代碼可以理解成:(部分用語(yǔ)可能不準(zhǔn)確)
在同步執(zhí)行階段:
async1執(zhí)行到await async2()時(shí)为居,sync2()返回一個(gè)Promise, 其resolve放入到回調(diào)隊(duì)列中,跳出async1杀狡,執(zhí)行new promise的resolve時(shí)蒙畴,該resolve也會(huì)被放入回調(diào)隊(duì)列中。然后執(zhí)行到console.log('end');呜象,此時(shí)同步執(zhí)行結(jié)束膳凝。
重點(diǎn)(執(zhí)行回調(diào)隊(duì)列):
此時(shí)async2()返回的 Promise的resolve會(huì)被執(zhí)行,即執(zhí)行await async2()董朝,此時(shí)await的Promise的resolve會(huì)被放入到新回調(diào)隊(duì)列鸠项。此時(shí)原回調(diào)隊(duì)列中new promise的resolve會(huì)被執(zhí)行,promise2字符被打印子姜,原回調(diào)隊(duì)列執(zhí)行完畢祟绊。
執(zhí)行新回調(diào)隊(duì)列:
await的Promise的resolve被執(zhí)行,console.log('async1 end')執(zhí)行哥捕。async1()返回的Promise的resolve會(huì)被放入到新回調(diào)隊(duì)列牧抽。
所有回調(diào)隊(duì)列執(zhí)行完畢,setTimeout執(zhí)行遥赚。