執行下面這段代碼,若是和你想的輸出順序一致,那麼你可能已經掌握了Js的異步編程,本文對你來講或許沒太大幫助。什麼,輸出順序和你想的不同?請往下看:編程
async function log(x){
console.log(x)
setTimeout(()=>{ console.log('H')},0);
new Promise((resolve,reject)=>{
console.log("G");
resolve();
}).then(()=>{
console.log('J')
})
console.log('I');
}
new Promise((resolve,reject)=>{
console.log('A');
resolve();
}).then(()=>{
console.log('B')
})
console.log('C');
setTimeout(function(){
console.log('D')
},0)
log('E')
console.log('F');
debugger;
複製代碼
執行代碼,開始第一輪tick
,首先遇到Promise
。bash
resolve()
,.then()
的回調會加入此輪tick
尾部0
秒後將回調函數內的操做加入下一輪tick
async
函數log()
0
秒後將回調函數內的操做加入下一輪tick
Promise
,輸出G,.then()
的回調會加入此輪tick
尾部tick
結束,執行tick
尾部的微任務
tick
另外,若是async
函數內部出現await
,那麼執行狀況是怎樣的呢?咱們來在async
函數中await
一個Promise
,代碼以下:異步
async function log(x){
console.log(x)
setTimeout(()=>{ console.log('H')},0);
new Promise((resolve,reject)=>{
console.log("G");
resolve();
}).then(()=>{
console.log('J')
})
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
await new Promise((resolve,reject)=>{
console.log('await 1');
resolve()
}).then(()=>{
console.log('await 2');
})
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
console.log('I');
}
複製代碼
你若是執行下代碼,會發如今插入await
以後,執行順序發生了很大變化:async
tick
async
函數log()
以前的順序沒有改變。輸出A、輸出C,且B加入此輪tick
尾部,D加入下一輪tick
。async
函數log()
0
秒後將回調函數內的操做加入下一輪tick
Promise
,輸出G,.then()
的回調會加入此輪tick
尾部await
的手中,嘿嘿,不過await
的是Promise
構造器,輸出await 1
await
會將當前async
函數的執行權交出,等待Promise
的狀態改變後,再繼續執行,而且await
返回的是一個Promise
。因此我理解爲await
以後的代碼加入了此輪tick
尾部(執行驗證發現,確實是這樣)。異步編程
tick
結束,輸出tick
await 2
tick
開始