當async/await遇到map和reduce

map

首先咱們來看看同步的map怎麼寫。redis

// 對數組全部元素乘2
[1,2,3].map(value => value * 2); // [2,4,6]
複製代碼

那若是map函數須要進行異步操做才能返回結果應該怎麼寫呢?數組

[1, 2, 3].map(async value => value * 2); // [Promise, Promise, Promise]
複製代碼

async函數執行完會返回Promise對象,map就直接接收後裝進新數組了,數組內容直接變成了三個Promise,這顯然不是咱們想要的結果,因此咱們要對Promise數組再進一步操做取出其中的值。異步

await Promise.all([1, 2, 3].map(async value => value * 2)) // [2,4,6]
複製代碼

這裏的Promise.all會將一個由Promise組成的數組依次執行,並返回一個Promise對象,該對象的結果爲數組產生的結果集。async

reduce

對於reduce來講,也是基本和map差很少的思路,只是須要提早將前一次的結果用await取出Prmose的值,再進行運算。函數

await [1, 2, 3].reduce(async(previousValue, currentValue) => await previousValue + currentValue, 0) // 6
複製代碼

filter

感受好簡單啊,那數組的異步filter能不能也像map這麼寫呢?ui

await Promise.all([1, 2, 3].filter(async value => value % 2 === 1)) // [1,2,3]

複製代碼

結果沒對啊,async返回的Promise被直接判斷成true,致使一個元素也沒被過濾掉。spa

const filterResults = await Promise.all([1, 2, 3]
                            .map(async value => (value % 2 === 1))); // [true,false,true]
[1, 2, 3].filter((value, index) => filterResults[index]); // [1,3]
複製代碼

這裏咱們使用了一個臨時數組配合前面map先獲取異步filter對應每一個元素的結果,而後再使用filter過濾數組,搞定~code

Promise庫

剛開寫asyncMap的時候,覺得其餘的方法也會這麼簡單,後來發現事情並沒簡單,只好找了個Promise庫 bluebird,專門處理這些異步操做~~~對象

除了提供有常見的map、filter、reduce、some以外,還提供了PromisifyAll,直接把回調庫Promise化。同步

var fs = require("fs");
Promise.promisifyAll(fs);
fs.readFileAsync("file.js", "utf8").then(...)
複製代碼

也支持第三方庫

var Promise = require("bluebird");
Promise.promisifyAll(require("redis"));
複製代碼
相關文章
相關標籤/搜索