当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"));
复制代码
相关文章
相关标签/搜索