JS非同步控制流及async實現細節分析(2)

發表於2015-11-29

4. map/filter/reject

在async中,each系列的方法一共有12個:

  • each/forEach
  • eachOf/forEachOf
  • eachLimit/forEachLimit
  • eachOfLimit/forEachOfLimit
  • eachSeries/forEachSeries
  • eachOfSeries/forEachOfSeries

這些方法的回撥函式簽名為callback(err),只有一個參數列示是否出錯,因此無法收集到每個非同步任務的結果。如果我們希望如下呼叫:

考慮到對於陣列而言,可以通過forEach來實現map功能,例如:

因此,在這裡,可以通過async.eachOf來實現map,程式碼邏輯如下:

同樣,mapLimitmapSeries也可以通過類似的方式實現。

filter功能的實現也是類似的方式,例如我們希望過濾出所有存在的檔案,期望的呼叫方式如下:

filter的實現如下:

同樣,filterLimitfilterSeries也可以通過類似的方式實現。

reject的實現與filter幾乎一樣,除了判斷條件不同之外,在async中的原始碼如下:

5. some/every/detect

some實現邏輯如下:

every與此類似,實現邏輯如下:

detect返回的是第一個執行為truthy的值,與some非常類似,只需要將cb(true)cb(false)分別替換為cb(val)cb(undefined)即可。

6. reduce/reduceRight

reducereduceRight主要通過async.eachOfSeries來實現,注意reduce相關的只有一個series版本,即只有序列執行的版本,因為涉及到reduce的操作往往是要依賴於上一次操作的返回值,因此不能夠並行執行。

這部分原始碼比較簡單,不做贅述。

7. sortBy

sortBy的思路是:

  • 首先通過async.map將陣列對映為一個新的陣列,新陣列中得每一項結構為{value: x, criteria: criteria}
    • x為原陣列中的元素
    • criteria為需要比較的標準
  • 新的陣列會作為第二個引數傳給async.map的回撥函式,在該回撥函式中,以criteria對新陣列進行排序
  • 從排好序的陣列中收集所有的value作為最終的結果集傳遞給sortBy的回撥函式

相關文章