1. 程式人生 > >初窺async,await

初窺async,await

首先是一道今日頭條的面試題:(聽說是今日頭條的並且已經爛大街了)

 1     async function async1() {
 2         console.log( 'async1 start' )
 3         await async2()
 4         console.log( 'async1 end' )
 5     }
 6     
 7     async function async2() {
 8         console.log( 'async2' )
 9     }
10     
11     console.log( 'script start' )
12 13 setTimeout( function () { 14 console.log( 'setTimeout' ) 15 }, 0 ) 16 17 async1(); 18 19 new Promise( function ( resolve ) { 20 console.log( 'promise1' ) 21 resolve(); 22 } ).then( function () { 23 console.log( 'promise2' ) 24 } )
25 26 console.log( 'script end' )

這個題我認為的順序和瀏覽器的順序一開始並不一樣,讓我一度以為瀏覽器出了問題。

首先需要了解promise,不然後面就很難理解下去。參見:http://es6.ruanyifeng.com/#docs/promise

async是什麼?

 簡單來講如果一個函式前面帶了async那麼,函式的返回值必定是一個promise的物件。如果返回值不是promise物件,會自動的去包裝為一個promise物件。

await是什麼?

 await可以算是async wait簡寫。等待async執行結果。

回到程式碼中,顯而易見首先列印的內容是‘script start’

,不需要解釋。

然後就是setTimeout,雖然時間是0但是隻有在這一輪事件迴圈的底部或者是事件佇列為空才會立即執行,很明顯既不是底部,事件佇列也還未執行完成。

下一個執行到async1();

async1中首先列印async1 start’,然後遇到await,await會阻塞後面的程式碼,先執行async外部的程式碼,所以會接著列印‘async2’;

之前的await中斷了當前async的執行,所以下一個執行的就是promise,promise是直接呼叫同步程式碼,所以接著就是‘promise1’;

因為會優先執行同步程式碼,所以接下來就是列印‘script end’;

執行完畢回到promise接著執行then列印‘promise2’,之後再次回到前面繼續執行resolve,但是因為引數為空,所以列印‘undefined’;(promise執行順序,具體參見:http://es6.ruanyifeng.com/#docs/promise)

這個時候await async2()執行結束,繼續async1後面的程式碼,列印‘async1 end’;

至此所以的事件佇列執行結束

前面說了,事件佇列為空才會執行setTimeout

所以正確的順序為:

    script start
    async1 start
    async2
    promise1
    script end
    promise2
    async1 end
    setTimeout

 有錯誤的話歡迎指正。