如何用Async/Await實作Promise Array的throttle

MengWei Chen
3 min readSep 27, 2017

--

這篇文章其實是上一篇讓JS array reduce與async/await共舞的小續集,起因是有網友討論到了在nodejs後端處理資料時,有更進階的應用需求,因此想到了比起循序執行Promise來說,有throttle的執行Promise Array可能更加實用。

先講一下到底什麼叫做throttle執行Promise Array好了,舉個例子,後端可能會收到一個來自前端的”userNameList”,這時候後端就要去把”userNameList“”透過查詢DB的方式取得每個”userName”的id並且將結果置換上去。

我們先不討論這個做法本身合不合理(其實可以把資料處理之後用WHERE IN 方式一次query),就這個case來說,假如userNameList有100個項目的話,依序查詢就顯得沒那麼有效率,但一口氣用Promise.all又會對DB跟Server造成較大的負擔,這就是本文的重點throttlePromise所要解決的問題~

我們可以設計一個throttlePromise Function來決定一次要同時執行幾個Promise!舉個例來說,100個Promise可以透過throttlePromise來限定一次執行4個Promise,並且依序分25次執行,透過這樣的做法就可以在效率跟server的負擔上取的一個平衡。

接下來廢話不多說,直接來看code

從上面的程式碼可以發現到,把上一篇文章所提到的async/await依序執行Promise的方式經過簡單的修改,先對輸入的Array進行預處理(將Array依照throttle參數分組),再將一組一組的Promise function Array透過Promise.all執行並將結果拆解後push進res Array,即可達到我們要的目的~

想看實際執行的樣子可以到codePen體驗!

不過事情還沒這樣結束~眼尖的朋友可能就會發現,這樣子的做法怎麼跟上一篇文章介紹的其中一種方式有87分像!沒錯就讓我們把整個function再整理一下

完整可執行的程式在這

我們原本的function拆成三個部分來看,分別是進行分組的splitEvery,還有真正執行Promise.all的sequencePromiseAll,還有最後的將res攤平的部分(因為sequencePromiseAll回傳的是一個二維陣列)。

這時候就可以很清楚的看到sequencePromiseAll其實就是上篇文章的法async/await解法,同理也可以把這個sequencePromiseAll用其他的方式改寫,例如

完整的程式在這

相信各位看完了這兩篇完章後,一定都對“依序執行Promise”有更深的認識~如過有什麼更好的方式或問題也歡迎跟我交流~

--

--