es6 async函式例項:按順序完成非同步操作
阿新 • • 發佈:2019-01-02
async函式例項:按順序完成非同步操作
實際開發中,經常遇到一組非同步操作,需要按照順序完成。比如,依次遠端讀取一組 URL,然後按照讀取的順序輸出結果。
ES6 Promise 的寫法如下。
function logInOrder(urls){
// 遠端讀取所有URL
const textPromises = urls.map(url =>{
return fetch(url).then(response => response.text());
});
// 按次序輸出
textPromises.reduce((chain, textPromise)=>{
return chain
.then(text => console.log(text));
},Promise.resolve());
}
上面程式碼使用fetch
方法,同時遠端讀取一組 URL。每個fetch
操作都返回一個
Promise 物件,放入textPromises
陣列。然後,reduce
方法依次處理每個
Promise 物件,然後使用then
,將所有 Promise 物件連起來,因此就可以依次輸出結果。
這種寫法不太直觀,可讀性比較差。下面是 async函式實現。
async function logInOrder(urls){
for(const
const response = await fetch(url);
console.log(await response.text());
}
}
上面程式碼確實大大簡化,問題是所有遠端操作都是繼發。只有前一個 URL 返回結果,才會去讀取下一個 URL,這樣做效率很差,非常浪費時間。我們需要的是併發發出遠端請求。
async function logInOrder(urls){
// 併發讀取遠端URL
const textPromises = urls.map(async url =>{
const response = await fetch(url);
return
});
// 按次序輸出
for(const textPromise of textPromises){
console.log(await textPromise);
}
}
上面程式碼中,雖然map
方法的引數是async
函式,但它是併發執行的,因為只有async
函式內部是繼發執行,外部不受影響。後面的for..of
迴圈內部使用了await
,因此實現了按順序輸出。