本文译自How to use async functions with Array.filter in Javascript - Tamás Sallai

0. 如何仅保留满足异步条件的元素

第一篇文章中,我们介绍了 async / await 如何帮助处理异步事件,但在异步处理集合时却无济于事。在本文中,我们将研究该filter函数,它可能是支持异步函数的最直观的方法。

1. Array.filter

filter函数仅保留通过条件的元素。它得到一个断言( predicate )函数,并且此函数返回 true / false 值。结果集合仅包含断言( predicate )返回 true 的元素。

const arr = [1, 2, 3, 4, 5];

const syncRes = arr.filter((i) => {
return i % 2 === 0;
}); console.log(syncRes);
// 2,4

2. filter 结合 map 使用

这次的异步版本要复杂一些,它分为两个阶段。第一个通过断言函数异步地映射数组,从而生成true / false 值。然后第二步是利用第一步的结果同步 filter

const arr = [1, 2, 3, 4, 5];

const asyncFilter = async (arr, predicate) => {
const results = await Promise.all(arr.map(predicate)); return arr.filter((_v, index) => results[index]);
} const asyncRes = await asyncFilter(arr, async (i) => {
await sleep(10);
return i % 2 === 0;
}); console.log(asyncRes);
// 2,4

或单行实现:

const asyncFilter = async (arr, predicate) => Promise.all(arr.map(predicate))
.then((results) => arr.filter((_v, index) => results[index]));

并发

上面的实现同时运行所有断言函数。通常,这很好,但是与所有其他功能一样,它可能会使某些资源变得过分紧张。幸运的是,由于上述实现依赖于此map因此可以使用相同的并发控件

4. filter 结合 reduce 使用

除了使用异步map与同步之外filter,异步reduce 也可以完成这项工作。由于它只是一个功能,因此即使没有提供相同级别的控制,结构也更加容易。

首先,从一个空数组([])开始。然后通过断言函数运行下一个元素,如果通过则将其追加到数组。如果没有,请跳过它。

// concurrently
const asyncFilter = async (arr, predicate) =>
arr.reduce(async (memo, e) =>
await predicate(e) ? [...await memo, e] : memo
, []);

请注意,await predicate(e)await memo 之前,这意味着这些将并行调用。

顺序处理

要在调用下一个谓词函数之前等待其结束,请更改await 的顺序:

// sequentially
const asyncFilter = async (arr, predicate) =>
arr.reduce(async (memo, e) =>
[...await memo, ...await predicate(e) ? [e] : []]
, []);

此实现等待上一个元素,然后根据断言(...[e]...[])的结果有条件地附加一个元素。

5. 结论

虽然异步filter是可能的,但它最初的工作方式看起来很奇怪。尽管并发控制仍然可用,但与其他异步功能相比,它们需要更多的计划去控制它。

推荐阅读

在 Array.filter 中正确使用 Async的更多相关文章

  1. 如何在 Array.forEach 中正确使用 Async

    本文译自How to use async functions with Array.forEach in Javascript - Tamás Sallai. 0. 如何异步遍历元素 在第一篇文章中, ...

  2. JavaScript笔记Array.filter(Boolean)

    ECMAScirpt5 中 Array 类中的 filter 方法使用目的是移除所有的 ”false“ 类型元素  (false, null, undefined, 0, NaN or an empt ...

  3. js array filter pop push shift unshift方法

    JavaScript Array filter() 方法  JavaScript Array 对象 实例 返回数组 ages 中所有元素都大于 18 的元素: var ages = [32, 33,  ...

  4. array.fliter无法正确过滤出我想要的数组

    var checked_list = state.files.filter(function(item, id){ // console.log('click the ' + item.id); re ...

  5. IoC容器Autofac(5) - Autofac在Asp.net MVC Filter中的应用

    Autofac结合EF在MVC中的使用,上一篇IoC容器Autofac(4) - Autofact + Asp.net MVC + EF Code First(附源码)已经介绍了.但是只是MVC中Co ...

  6. 浅谈JavaScript中的defer,async

    引言 开始重读<<JavaScript高级程序设计>>一书,看到关于JavaScript中关于defer.async的部分.网上查询了点资料,觉得蛮好的.现在总结下. defe ...

  7. 在Java filter中调用service层方法

    在项目中遇到一个问题,在 Filter中注入 Serivce失败,注入的service始终为null.如下所示: public class WeiXinFilter implements Filter ...

  8. 如何在Java Filter 中注入 Service

    在项目中遇到一个问题,在 Filter中注入 Serivce失败,注入的service始终为null.如下所示: public class WeiXinFilter implements Filter ...

  9. android中正确导入第三方jar包

    android中正确导入第三方jar包 andriod中如果引入jar包的方式不对就会出现一些奇怪的错误. 工作的时候恰好有一个jar包需要调用,结果用了很长时间才解决出现的bug. 刚开始是这样引用 ...

随机推荐

  1. def跨域+jwt

    1.跨域 由于浏览器具有“同源策略”的限制.如果在同一个域下发送ajax请求,浏览器的同源策略不会阻止.如果在不同域下发送ajax,浏览器的同源策略会阻止. 总结 域相同,永远不会存在跨域. crm, ...

  2. Java安装和配置

    一. Java安装和配置 1.JDK下载地址: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-21331 ...

  3. 记Android R(SDK=30)系统执行UiAutomator1.0异常

    最近Android发布了AndroidStudio 3.6稳定版,升级后明显能体验到好多细节的提升,最大的提升莫过于可以创建Android R预览版的模拟器了,并且模拟器可以设置多个尺寸的屏幕.And ...

  4. go例子(三) 使用context实现发牌手策略

    使用context包实现发牌手策略, 发牌手策略:罗永浩在介绍TNT工作站时描述,将一个任务分发给多个处理者处理,谁先处理完使用谁的结果,取消其他的处理者的任务. 经典的例子:同时在百度.google ...

  5. ant-design-pro 如何打包成 本地html,双击即可查看

    由于 ant-design-pro 的 mock 是一个单独的服务,所以没有办法整合到一起打包.暂时我是没有找到. 所以解决方案就是不用 mock . 由于 系统有异步调取,所以一旦有异步调取就会失败 ...

  6. Jenkins的制品管理

    Jenkins的制品管理 制品是什么? 也叫产出物或工件.制品是软件开发过程中产生的多种有形副产品之一.广义的制品包括用例.UML图.设计文档等.而狭义的制品就可以简单地理解为二进制包.虽然有些代码是 ...

  7. Analysis of endogenous peptides released from osteoarthritic cartilage unravels novel pathogenic markers (解读人:李琼)

    文献名:Analysis of endogenous peptides released from osteoarthritic cartilage unravels novel pathogenic ...

  8. ysoserial分析【二】7u21和URLDNS

    目录 7u21 gadget链分析 hashCode绕过 参考 URLDNS 7u21 7u21中利用了TemplatesImpl来执行命令,结合动态代理.AnnotationInvocationHa ...

  9. intern()方法的使用

    intern() intern方法的作用是:如果字符串常量池中已经包含一个字符串等于此String对象的字符串,则返回常量池中的这个String对应的对象, 否则将其添加到常量池并返回常量池中的引用. ...

  10. 一起学习vue源码 - Vue2.x的生命周期(初始化阶段)

    作者:小土豆biubiubiu 博客园:https://www.cnblogs.com/HouJiao/ 掘金:https://juejin.im/user/58c61b4361ff4b005d9e8 ...