[TOC] #### 1. 前言 ---- async/await 是 ES7 提出的基于 Promise (ES6 中提出的) 的解決異步的最終方案 async + await 的作用: 簡(jiǎn)化 promise 的異步操作,把 promise 的異步操作編程變?yōu)橥降膶?xiě)法 async 將一個(gè)函數(shù)標(biāo)記為異步函數(shù),await 需要在異步函數(shù)中使用,標(biāo)記當(dāng)前操作是異步操作 async + await 必須配合 promise 使用,同時(shí) async 和 await 必須一起使用。即 await 必須在 async 標(biāo)記的函數(shù)中使用 #### 2. 獲取成功的結(jié)果 --- 在 vue 腳手架和 uniapp 中經(jīng)常使用的寫(xiě)法 ``` function getProfile() { return new Promise((resolve, reject) => { // 使用定時(shí)器模擬接口請(qǐng)求 setTimeout(() => { resolve({ code: 200, msg: "用戶信息", data: { id: 1, name: "liang" } }) }, 3000); }); } // 以下代碼會(huì)執(zhí)行 輸入 123 再執(zhí)行輸出 res function loadData() { getProfile().then(res => { console.log(res); }) console.log(123); } // 下面寫(xiě)法會(huì)使 getProfile() 先執(zhí)行 // 等待三秒后執(zhí)行完再把得到的結(jié)果賦值給左邊的res,然后再繼續(xù)往下執(zhí)行 async function loadData() { const res = await getProfile() console.log(res); console.log(123); } ``` #### 3. 獲取失敗的結(jié)果 --- 當(dāng) Promise 拋出錯(cuò)誤信息時(shí),控制臺(tái)默認(rèn)是直接拋出異常的 ``` reject('接口請(qǐng)求失敗') ``` ![](https://img.itqaq.com/art/content/0d81551f38c101e81774409ba7bc4b40.png) 可以使用 try ... catch 捕獲 promise 拋出的錯(cuò)誤 ``` try { const res = await getProfile() console.log(res); } catch (error) { console.log('error: ', error); } ``` #### 4. 多個(gè) Promise 的場(chǎng)景 --- 使用 Promise Promise.all 的參數(shù)是一個(gè)數(shù)組,數(shù)組的每一項(xiàng)是一個(gè)返回的 promise 的函數(shù)調(diào)用 ```javascript Promise.all([getProfile(), getProfile()]).then(res => { console.log(res, 'res'); }) ``` 使用 await 因?yàn)?Promise.all 返回的也是一個(gè) Promise,所以也可以使用 await ```javascript async function loadData() { const res = await Promise.all([getProfile(), getProfile()]) console.log(res); } ``` #### 5. async 標(biāo)記函數(shù) --- 使用 async 標(biāo)記一個(gè)函數(shù),那么當(dāng)調(diào)用這個(gè)函數(shù)時(shí),該函數(shù)會(huì)返回一個(gè) promise 對(duì)象 如果沒(méi)有在 async 函數(shù)中 return ,那么 promise 對(duì)象的 resolve 就是 undefined 如果在 async 函數(shù)中寫(xiě)了 return,那么 promise 對(duì)象的 resolve 就是 return 的值 如果 async 里的代碼都是同步的,那么這個(gè)函數(shù)被調(diào)用就會(huì)同步執(zhí)行 ``` async function fn(){ console.log('a') } fn() console.log('b') //a //b ``` #### 6. await 等待異步操作執(zhí)行完成 --- 右側(cè)的表達(dá)式的結(jié)果就是 await 要等的東西,等到之后,對(duì)于 await 來(lái)說(shuō),分兩個(gè)情況。是 promise 對(duì)象,不是 promise 對(duì)象 ``` const res = await getProfile() ``` 如果不是 promise 對(duì)象,await 會(huì)阻塞后面的代碼,先執(zhí)行 async 外面的同步代碼,再回到 async 內(nèi)部,把這個(gè)非 promise 的東西,作為 await 表達(dá)式的結(jié)果 ``` function fn() { console.log(1) return 'this is return' } async function f1() { const res = await fn() console.log(2) console.log(res); } f1() console.log(3) //1 //3 //2 // this is return ``` 如果 await 等到的是一個(gè) promise 對(duì)象,await 也會(huì)暫停 async 后面的代碼,先執(zhí)行 async 外面的同步代碼,等著 Promise 對(duì)象 fulfilled,然后把 resolve 的參數(shù)作為 await 表達(dá)式的運(yùn)算結(jié)果 ``` function fn() { console.log(1) return new Promise((resolve, reject) => { setTimeout(() => { resolve('this is return') }, 1500); }); } async function f1() { const res = await fn() console.log(2) console.log(res); } f1() console.log(3) //1 //3 //2 // this is return ``` #### 6. async + await 相關(guān)文章推薦 --- async 和 await 【簡(jiǎn)書(shū)】: [https://www.jianshu.com/p/b4fd76c61dc9](https://www.jianshu.com/p/b4fd76c61dc9)