setTimeout,async, promise執行順序總結
阿新 • • 發佈:2019-01-01
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
分析:
await async2();//執行這一句後,輸出async2後,await會讓出當前執行緒,將後面的程式碼加到任務佇列中,然後繼續執行test()函式後面的同步程式碼
執行到setTimeout函式時,將其回撥函式加入佇列(此佇列與promise佇列不是同一個佇列,執行的優先順序低於promise)。繼續執行
建立promise物件裡面的程式碼屬於同步程式碼,promise的非同步性體現在then與catch處,所以promise1被輸出,然後將then函式的程式碼加入佇列,繼續執行同步程式碼,輸出script end。
至此同步程式碼執行完畢,開始從佇列中調取任務執行,由於剛剛提到過,setTimeout的任務佇列優先順序低於promise佇列,所以首先執行promise佇列的第一個任務,即執行async1中await後面的程式碼,輸出async1 end。
然後執行then方法的部分,輸出promise2。最後promise佇列中任務執行完畢,再執行setTimeout的任務佇列,輸出settimeout。
至此,該題的輸出結果分析完畢了,這類的執行結果可以用一句話總結,先執行同步程式碼,遇到非同步程式碼就先加入佇列,然後按入隊的順序執行非同步程式碼,最後執行setTimeout佇列的程式碼。
補充一下佇列任務優先順序:promise.Trick()>promise的回撥>setTimeout>setImmediate