ES7前端異步玩法:async/await理解
本文轉載於:https://www.cnblogs.com/leungUwah/p/7932912.html
說明:怕原作者鏈接失效,備份一份
在最新的ES7(ES2017)中提出的前端異步特性:async、await。
什麽是async、await?
async顧名思義是“異步”的意思,async用於聲明一個函數是異步的。而await從字面意思上是“等待”的意思,就是用於等待異步完成。並且await只能在async函數中使用
通常async、await都是跟隨Promise一起使用的。為什麽這麽說呢?因為async返回的都是一個Promise對象同時async適用於任何類型的函數上。這樣await得到的就是一個Promise對象(如果不是Promise對象的話那async返回的是什麽 就是什麽);
await得到Promise對象之後就等待Promise接下來的resolve或者reject。
來看一段簡單的代碼:
async function testSync() { const response = await new Promise(resolve => { setTimeout(() => { resolve("async await test..."); }, 1000); }); console.log(response); } testSync();//async await test...
就這樣一個簡單的async、await異步就完成了。使用async、await完成異步操作代碼可讀與寫法上更像是同步的,也更容易讓人理解。
async、await串行並行處理
串行:等待前面一個await執行後接著執行下一個await,以此類推
async function asyncAwaitFn(str) { return await new Promise((resolve, reject) => { setTimeout(() => { resolve(str) }, 1000); }) } const serialFn= async () => { //串行執行 console.time(‘serialFn‘) console.log(await asyncAwaitFn(‘string 1‘)); console.log(await asyncAwaitFn(‘string 2‘)); console.timeEnd(‘serialFn‘) } serialFn();
可以看到兩個await串行執行的總耗時為兩千多毫秒。
並行:將多個promise直接發起請求(先執行async所在函數),然後再進行await操作。
async function asyncAwaitFn(str) { return await new Promise((resolve, reject) => { setTimeout(() => { resolve(str) }, 1000); }) } const parallel = async () => { //並行執行 console.time(‘parallel‘) const parallelOne = asyncAwaitFn(‘string 1‘); const parallelTwo = asyncAwaitFn(‘string 2‘) //直接打印 console.log(await parallelOne) console.log(await parallelTwo) console.timeEnd(‘parallel‘) } parallel()
通過打印我們可以看到相對於串行執行,效率提升了一倍。在並行請求中先執行async的異步操作再await它的結果,把多個串行請求改為並行可以將代碼執行得更快,效率更高。
async、await錯誤處理
JavaScript異步請求肯定會有請求失敗的情況,上面也說到了async返回的是一個Promise對象。既然是返回一個Promise對象的話那處理當異步請求發生錯誤的時候我們就要處理reject的狀態了。
在Promise中當請求reject的時候我們可以使用catch。為了保持代碼的健壯性使用async、await的時候我們使用try catch來處理錯誤。
async function catchErr() { try { const errRes = await new Promise((resolve, reject) => { setTimeout(() => { reject("http error..."); }, 1000); ); //平常我們也可以在await請求成功後通過判斷當前status是不是200來判斷請求是否成功 // console.log(errRes.status, errRes.statusText); } catch(err) { console.log(err); } } catchErr(); //http error...
ES7前端異步玩法:async/await理解