在JavaScript的異步代碼執行時:promise
若是遇到await,就將await執行後,後面的代碼放入等待隊列(由於async和await的本質仍是promise的運用,返回的是一個promise對象)。bash
備註:async是generator的語法糖, 只是把generator的function後面的*換成了前面的async,把yield換成了await。運行原理是同樣的,都是爲了解決JS的異步操做問題,畢竟JS是單線程的。異步
若是遇到promise的then和catch,也一樣放入等待隊列,兩者優先級相同,在同步代碼結束後按照隊列的先入先出原則執行。async
若是遇到setTimeout的話,也是一樣放在等待隊列,可是是不一樣的等待隊列,優先級低於await和promise。函數
async function async1() {
console.log("async1 start");
await async2(); // 關鍵點1
console.log("async1 end");
}
async function async2() {
console.log( 'async2');
}
console.log("script start");
setTimeout(function () {
// 關鍵點2
console.log("settimeout");
},0);
async1();
new Promise(function (resolve) {
console.log("promise1");
// 關鍵點3
resolve();
}).then(function () {
console.log("promise2");
});
console.log('script end');
複製代碼
以上代碼片斷的執行結果爲:ui
> "script start"
> "async1 start"
> "async2"
> "promise1"
> "script end"
> "async1 end"
> "promise2"
> "settimeout"
複製代碼
----------------------------------------- 同步代碼部分 --------------------------------------------spa
console.log("script start");
開始,遇到setTimeout直接丟到等待隊列的最末端(實際上是另外一個優先級較低的等待隊列的隊首,姑且認爲是promise等待隊列的最末端)。console.log("async1 start");
爲同步代碼,直接輸出,而後遇到了await async2
。console.log( 'async2');
,在執行事後立刻將await後面的代碼所有放到promise等待隊列中。console.log("promise1");
爲同步代碼,當即執行。而後發現這個promise後面緊跟真一個then(),不要猶豫直接將這個promise放入剛剛已經存放了await的等待隊列中。console.log('script end');
被找到並執行。----------------------------------------- 異步代碼部分 --------------------------------------------線程
如今的異步代碼等待隊列中,包含await函數後面的全部代碼,和promise的then()code
console.log("async1 end");
。console.log("promise2");
。console.log("settimeout");
。√到此爲止全部代碼執行完畢。對象