async/await是一種異步解決方案,相對於其餘異步解決方案,async/await語法在使用上是比較簡單的,使用起來跟同步方法沒有太大差別。promise
function promiseFn () {
return new Promise((resolve, reject) => {
resolve(1);
});
}
async function asyncFn() {
const num = await promiseFn();
console.log(num);
}
asyncFn(); // 1
複製代碼
await 後面的內容,若是不是返回一個Promise,則會用Promise.resolve()進行一個隱式調用,確保返回的是一個Promise。異步
function notPromiseFn () {
return 1;
}
async function asyncFn () {
const num = await notPromiseFn();
console.log(num);
}
async function asyncFn2 () {
const num = await 666;
console.log(num);
}
asyncFn(); // 1
asyncFn2(); // 666
複製代碼
因此,其實咱們能夠不用管await後面返回的類型,都是可使用async/await的。但若是不是異步函數的話,其實就沒有必要這麼用了,直接用同步的寫法就好,畢竟async/await的目的就是用同步的模式來實現異步的操做的,同步代碼也使用async/await就有點畫蛇添足了。async
異常處理是平時編寫代碼中必需要考慮的問題,所以,在async/await中也必需要對異常狀況進行處理。函數
function errorPromiseFn(type) {
return new Promise((resolve, reject) => {
if (type === 'error') {
throw new Error('Error');
}
resolve(404);
});
}
async function errorFn() {
try {
const res = await errorPromiseFn('error');
console.log(res);
} catch (err) {
console.error(err);
}
}
errorFn('error'); // 異常會被俘獲
複製代碼
咱們知道,同步代碼都是串行執行的。但有的時候,咱們並不但願都是串行執行的。好比,在須要請求多個沒有相互依賴的接口數據時,最佳解決方案是並行執行。oop
function getData1() {
return new Promise((resolve, reject) => {
fetch(url).then(res => resolve(res));
});
}
function getData2(url) {
return new Promise((resolve, reject) => {
fetch(url).then(res => resolve(res));
});
}
async serialGetAllData() {
// 建立promise並等待處理結果
const data1 = await getData1();
// 等待前面的處理結果完成,再建立promise並處理結果
const data2 = await getData2();
return {data1, data2};
}
serialGetAllData();
複製代碼
上面的serialGetAllData就行串行的先去請求data1再去請求data2,可是data2其實並不須要等到data1請求完成後再去執行。所以,咱們但願他們可以同步的進行。fetch
學過Promise的應該知道,Promise.all是支持多個Promise並行請求的。那麼,在async/await中,咱們就能夠藉助Promise.all來實現並行請求了。ui
async parallelGetAllData() {
const [data1, data2] = await Promise.all([
getData1(),
getData2()
]);
return {data1, data2};
}
parallelGetAllData();
複製代碼
除了Promise.all方法外,還有另一種方法實現並行操做:先建立Promise再使用await。url
async parallelGetAllData() {
// 建立多個promise實例
const promise1 = getData1();
const promise2 = getData2();
// 同時等待多個promise的結果,
// 假如promise1耗時三秒,promise2耗時兩秒,
// 因爲promise1和promise2同時進行請求,
// 所以只需3秒就能夠獲得data1和data2了
const data1 = await promise1;
const data2 = await promise2;
return {data1, data2};
}
複製代碼
有時候,咱們須要在循環體中去進行異步操做spa
async function serialLoop() {
let promises = [getData1, getData2];
for (let promise of promises) {
const data = await promise();
console.log(data);
}
}
serialLoop();
複製代碼
很顯然,上面的代碼是串行執行的,若是getData1須要3秒,getData2須要2秒,那麼整個過程就須要5秒才能執行完成。code
在上一節中,咱們知道了async/await能夠改造爲並行執行
async function parallelLoop() {
let promises = [getData1(), getData2()];
for (let promise of promises) {
const data = await promise;
console.log(data);
}
}
parallelLoop();
複製代碼
這樣,就只須要3秒就能夠執行完了。