await
的意思就是等待。它後面能夠跟一個表達式。若是是值(如字符串、數字、普通對象等等)的話,返回值就是自己的值。promise
對象。await
會等待這個promise
的狀態由pending
轉爲fulfilled
或者rejected
。在此期間它會阻塞,延遲執行await語句後面的語句。promise
對象的結果是resolve
,它會將resolve
的值,做爲await
表達式的運算結果。 其實await
與async
自己就是promise
化編程的一種語法糖。對比一下兩種寫法。編程
// 異步promise化的函數--模擬請求後端接口 function asyncFn () { return new Promise(function (resolve, reject) { setTimeout(function () { if (true) { console.log('resolve console') resolve('resolve return') } else { reject('reject return') } }, 2000) }) } // promise asyncFn().then((res) => { console.log(res) }, (err) => { console.log(err) }) // await try { var res = await asyncFn() console.log(res) } catch(err) { console.log(err) } // 若是有第二次請求的話,promise須要在then方法繼續調用,再用then接受,過多的嵌套依然會增長閱讀難度。而await async只須要像寫同步代碼同樣繼續書寫就能夠,它是解決異步編程回調地獄的終極手段。
// ps:因爲js自己如今已經限制了await必須用在async函數中,不然會報錯。因此請將下面的複製粘貼到瀏覽器控制檯查看結果 function asyncFn () { return new Promise(function (resolve, reject) { setTimeout(function () { if (true) { console.log('resolve console') resolve('resolve return') } else { reject('reject return') } }, 2000) }) } var value1 = await asyncFn() var value2 = await 'plain text' console.log(value1) console.log(value2) //瀏覽器會依次打印 ‘resolve console’ ‘resolve return’ ‘plain text’
若是你對結果有疑問,能夠將asyncFn前面的await去掉,再在瀏覽器控制檯執行一次。後端
這兩次對比一下,會發現第二次的resolve console
是最後打印出來的,而第一次的是第一個打印的。promise
根本緣由就是第一次代碼中await
阻塞了後面語句的執行,等待promise
肯定結果後繼續執行後面語句。瀏覽器
根據前兩例可想而知,若是兩個await
的後面跟着的都是promise
對象。那麼第二個await等待的時間是它自己等待的時間加上第一個await
等待的時間異步
function asyncFn1 () { return new Promise(function (resolve, reject) { setTimeout(function () { if (true) { console.log('resolve console1') resolve('resolve return1') } else { reject('reject return1') } }, 2000) }) } function asyncFn2 () { return new Promise(function (resolve, reject) { setTimeout(function () { if (true) { console.log('resolve console2') resolve('resolve return2') } else { reject('reject return2') } }, 2000) }) } var value1 = await asyncFn1() var value2 = await asyncFn2() // 複製並執行,會發現2s後打印了‘resolve console1’,4s後打印了‘resolve console2’
// 已經知道了await會阻塞代碼的執行,若是咱們在實際開發中有這樣的代碼。 function fn () { // 假設request是請求後端接口 var value = await request() console.log(value) // ... } fn() var arr = [] arr.push('1') // ...其餘不依賴後端接口邏輯
在fn調用後,因爲await
的阻塞,必然會影響到下面的邏輯。在實際開發中,若是後端接口5s才響應,那麼下面的代碼就須要等待5s。顯然這是不合理的,爲了解決這種現象,就須要async
聲明。async
以前咱們知道了await
會阻塞代碼的執行。而解決這個弊端的手段就是async
聲明。異步編程
async function asyncFn () { return 'async' } console.log(asyncFn())
控制檯打印一下,會發現打印的是一個promise
對象。並且是Promise.resolve
對象。resolve
的值就是asyncFn
的函數返回值async
。函數
若是函數沒有返回值的話,它天然返回的會是Promise.resolve(undefined)
。code
其實之因此async
聲明能解決await
的阻塞問題,就是由於async
聲明將函數做了一層promise
包裝,這樣內部的異步操做其實就是由pending
轉爲resolve
或者reject
的過程。這樣函數自己就可以隨意調用,函數內部的await
也不會再影響到函數外部的代碼執行。對象