Async/Await 代替 Promise.all()
新調料,新味道
基本概念
Promise
儲存著一個未來可用的值的代理,本身是嚴格按照非同步方式執行的
function resolveUnderThreeSeconds(delay) { return new Promise(function(resolve, reject) { setTimeout(() => resolve('success'), delay) setTimeout(() => reject('fail'), 3000) }) } resolveUnderThreeSeconds(2000) .then(res => { console.log('res', res) }) .catch(err => { console.log('err', err) })
編寫非同步程式碼時,可能兩個任務中的一個任務會依賴另一個任務的結果,因此這兩個任務必須序列執行
Promise.all()
方法接受一個 Promise
陣列,陣列內所有 Promise
執行成功後,根據傳入順序返回各個 Promise
的結果資料,其中一個被拒絕,即會暫停,返回錯誤資訊
const p1 = Promise.reject('failed') const p2 = Promise.resolve('success') const p3 = Promise.resolve('success') const p = Promise.all([p1, p2, p3]).catch(err => console.log(err))
Async/Await
async 函式兼顧了基於 Promise 的實現和生成器風格的同步寫法
function resolveAfter2Seconds() { return new Promise(resolve => { setTimeout(() => { resolve('resolved'); }, 2000); }); } async function asyncCall() { console.log('calling'); var result = await resolveAfter2Seconds(); console.log(result); // expected output: 'resolved' } asyncCall();
實現
功能分析
關鍵:Promise.all()
傳入的是 promise
陣列,陣列內所有 Promise
執行成功後,根據傳入順序返回各個 Promise
的結果資料,其中一個被拒絕,即會暫停,並返回錯誤資訊
陣列進入 async
函式,迴圈使用 async/await
執行進入的陣列函式,然後將函式結果組成陣列,最後返回該陣列即可
try/catch
可獲取 async
函式內,任意 await
的錯誤,即可滿足 其中一個被拒絕,即會暫停,並返回錯誤資訊
的功能
async function asyncAlls(jobs) { try { // 迴圈執行 let results = jobs.map(async job => await job) let res = [] // 組合陣列 for (const result of results) { res.push(await result) } return res } catch (error) { throw new Error(error) } }
例項展示
function doJob(x, sec) { if (!x) { throw new Error('test error') } return new Promise(resolve => { console.log('Start: ' + x) setTimeout(() => { console.log('End: ' + x) resolve(x) }, sec * 100) }) } async function asyncAlls(jobs) { try { let results = jobs.map(async job => await job) let res = [] for (const result of results) { res.push(await result) } return res } catch (error) { throw new Error(error) } } (async function() { try { const all1 = await asyncAlls([doJob(1, 1), doJob(2, 1), doJob(0, 1), doJob(4, 1)]) console.log('all1', all1) } catch (error) { console.log('0', error) } try { const all2 = await asyncAlls([doJob(5, 1), doJob(6, 1), doJob(7, 1), doJob(8, 1)]) console.log('all2', all2) } catch (error) { console.log('1', error) } })()
總結
本文思路源於一個面試題,迫於好奇,花了點時間實現了一下,期間有諸多不懂的地方也請教了許多小夥伴,感謝諸位小夥伴解惑
參考
相關文章
- 面試向:Async/Await 代替 Promise.all()面試AIPromise
- async/await 和 promise/promise.all 的示例AIPromise
- 結合async await,動態設定Promise.all()AIPromise
- Async +AwaitAI
- Async/awaitAI
- async和awaitAI
- 理解 async/awaitAI
- 【譯】Async/Await(三)——Aysnc/Await模式AI模式
- async await詳解AI
- 淺談async/awaitAI
- JavaScript async await 使用JavaScriptAI
- JavaScript Promises, async/awaitJavaScriptPromiseAI
- 小程式使用 async awaitAI
- 理解JavaScript的async/awaitJavaScriptAI
- 深入理解 async / awaitAI
- WPF WebClient EAP async awaitWebclientAI
- 重學JS:async/awaitJSAI
- 理解Task和和async awaitAI
- 理解 js的 async/awaitJSAI
- [Javascript] Promise question with async awaitJavaScriptPromiseAI
- async和await的使用AI
- 【譯】Async/Await(二)——FuturesAI
- await is only valid in async functionAIFunction
- 【譯】Async/Await(四)—— PinningAI
- [譯]JavaScript Symbols, Iterators, Generators, Async/Await, and Async IteratorsJavaScriptSymbolAI
- JavaScript 的 async/await 理解(4)JavaScriptAI
- 非同步神器async-await非同步AI
- ES6 - async&awaitAI
- 使用async await 封裝 axiosAI封裝iOS
- 如何正確使用async/await?AI
- Promise和async await詳解PromiseAI
- 理解 es7 async awaitAI
- [譯文] JavaScript async 和 awaitJavaScriptAI
- 如何講清楚async和await?AI
- Async,Await 深入原始碼解析AI原始碼
- [譯]帶你理解 Async/awaitAI
- 【譯】JavaScript中的async/awaitJavaScriptAI
- ES2017 —— async await原理AI