在最新的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。
來看一段簡單的代碼:
1 async function testSync() {
2 const response = await new Promise(resolve => {
3 setTimeout(() => {
4 resolve("async await test...");
5 }, 1000);
6 });
7 console.log(response);
8 }
9 testSync();//async await test...
就這樣一個簡單的async、await異步就完成了。使用async、await完成異步操作代碼可讀與寫法上更像是同步的,也更容易讓人理解。
async、await串行並行處理
串行:等待前面一個await執行后接着執行下一個await,以此類推
1 async function asyncAwaitFn(str) {
2 return await new Promise((resolve, reject) => {
3 setTimeout(() => {
4 resolve(str)
5 }, 1000);
6 })
7 }
8
9 const serialFn = async () => { //串行執行
10
11 console.time('serialFn')
12 console.log(await asyncAwaitFn('string 1'));
13 console.log(await asyncAwaitFn('string 2'));
14 console.timeEnd('serialFn')
15 }
16
17 serialFn();

可以看到兩個await串行執行的總耗時為兩千多毫秒。
並行:將多個promise直接發起請求(先執行async所在函數),然后再進行await操作。
1 async function asyncAwaitFn(str) {
2 return await new Promise((resolve, reject) => {
3 setTimeout(() => {
4 resolve(str)
5 }, 1000);
6 })
7 }
8 const parallel = async () => { //並行執行
9 console.time('parallel')
10 const parallelOne = asyncAwaitFn('string 1');
11 const parallelTwo = asyncAwaitFn('string 2')
12
13 //直接打印
14 console.log(await parallelOne)
15 console.log(await parallelTwo)
16
17 console.timeEnd('parallel')
18
19
20 }
21 parallel()

通過打印我們可以看到相對於串行執行,效率提升了一倍。在並行請求中先執行async的異步操作再await它的結果,把多個串行請求改為並行可以將代碼執行得更快,效率更高。
async、await錯誤處理
JavaScript異步請求肯定會有請求失敗的情況,上面也說到了async返回的是一個Promise對象。既然是返回一個Promise對象的話那處理當異步請求發生錯誤的時候我們就要處理reject的狀態了。
在Promise中當請求reject的時候我們可以使用catch。為了保持代碼的健壯性使用async、await的時候我們使用try catch來處理錯誤。
1 async function catchErr() {
2 try {
3 const errRes = await new Promise((resolve, reject) => {
4 setTimeout(() => {
5 reject("http error...");
6 }, 1000);
7 );
8 //平常我們也可以在await請求成功后通過判斷當前status是不是200來判斷請求是否成功
9 // console.log(errRes.status, errRes.statusText);
10 } catch(err) {
11 console.log(err);
12 }
13 }
14 catchErr(); //http error...
以上就是async、await使用try catch 處理錯誤的方式。
雖然async、await也使用到了Promise但是卻減少了Promise的then處理使得整個異步請求代碼清爽了許多。
以上就是個人對ES7 async、await的一些個人理解,后續有其他的會補充更新,寫的不好的地方歡迎各位大神指正,謝謝!

