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

0. 如何异步遍历元素

第一篇文章中,我们介绍了async / await如何帮助处理异步事件,但在异步处理集合时却无济于事。在本文中,我们将研究该forEach功能,当您需要为集合中的每个元素运行一段代码时,该功能将非常有用。

1. forEach

forEach函数类似于map,但是它不转换值并使用结果,而是为每个元素运行该函数并丢弃结果(这里可以理解成是否有return值)。实际上,重要的部分是调用函数的副作用。

例如,将每个元素同步打印到控制台:

const arr = [1, 2, 3];

arr.forEach((i) => {
console.log(i);
}); // 1
// 2
// 3 console.log("Finished sync");
// Finished sync

由于结果并不重要,因此可以使用异步函数作为迭代器:

const arr = [1, 2, 3];

arr.forEach(async (i) => {
// each element takes a different amount of time to complete
await sleep(10 - i);
console.log(i);
}); console.log("Finished async");
// Finished async // 3
// 2
// 1

2. 控制时间

2.1 等待完成

但是,并不奇怪,该函数被异步调用,并且程序执行超出了调用范围。这是与同步版本的重要区别,因为在执行下一行时,同步forEach已经完成,而异步版本尚未完成。这就是为什么“完成的异步”日志出现在元素之前的原因。

要在继续进行之前等待所有函数调用完成,可以使用带有Promise.allmap,并丢弃结果:

const arr = [1, 2, 3];

await Promise.all(arr.map(async (i) => {
await sleep(10 - i);
console.log(i);
})); // 3
// 2
// 1 console.log("Finished async");
// Finished async

进行此更改后,“完成的异步操作”排在最后。

2.2 顺序处理

但是请注意,迭代函数是并行调用的。要忠实地遵循同步forEach,要先使用带await memoreduce

const arr = [1, 2, 3];

await arr.reduce(async (memo, i) => {
await memo;
await sleep(10 - i);
console.log(i);
}, undefined); // 1
// 2
// 3 console.log("Finished async");
// Finished async

这样,元素依次依次处理,程序执行将等待整个数组完成后再继续。

3. 结论

异步forEach易于使用,但是是否应使用forEachmapreduce取决于计时的要求。如果您只想在任何时候运行这些功能,请使用forEach。如果要确保继续操作之前完成操作,请使用map。最后,如果您需要一个一个地运行它们,请使用reduce

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

  1. 在 Array.filter 中正确使用 Async

    本文译自How to use async functions with Array.filter in Javascript - Tamás Sallai. 0. 如何仅保留满足异步条件的元素 在第一 ...

  2. 如何在Crystal Portlet中正确返回JSON数据给AJAX请求?

    当Crystal Portlet中需要采用Ajax请求,并让后台返回Json数据时,如何才能正确.方便的返回Json数据呢? 以下两种方法均可: 方法一:Ajax请求时,采用RenderURL,对应P ...

  3. 为什么 array.foreach 不支持 async/await

    一.背景 react 项目中,渲染组件时,显示的数据一直有问题,本来以为是 react 组件的问题,后来才发现罪魁祸首在 fetch 数据的过程,因为我用了 async/await ,而却搭配了 fo ...

  4. 【转载】如何在 Kaggle 首战中进入前 10%

    本文转载自如何在 Kaggle 首战中进入前 10% 转载仅出于个人学习收藏,侵删 Introduction 本文采用署名 - 非商业性使用 - 禁止演绎 3.0 中国大陆许可协议进行许可.著作权由章 ...

  5. 关于在forEach中使用await的问题

    先说需求,根据数组中的ID值,对每个ID发送请求,获取数据进行操作. 首先肯定考虑用forEach 或者 map对数组进行遍历,然后根据值进行操作,但是请求是个异步操作,forEach又是一个同步操作 ...

  6. [Laravel-Swagger]如何在 Laravel 项目中使用 Swagger

    如何在 Laravel 项目中使用 Swagger http://swagger.io/getting-started/ 安装依赖 swagger-php composer require zirco ...

  7. 如何在eclipse jee中创建Maven project并且转换为Dynamic web project

    如何在eclipse jee中创建Maven project并且转换为Dynamic web project 注意:该文档只针对以下eclipse版本,如图 为了方便,我将我本地的压缩包放在了微云网盘 ...

  8. BITED-Windows8应用开发学习札记之三:如何在Win8应用中实现数据绑定

    在微软官方提供的资源中,我们可以看到SampleDataSource.cs已经拥有了定义好了相应的数据结构以及实现类: 建立本地数据 由于我们已经有数据以及相应的数据类,我们需要做的仅仅是将数据放进数 ...

  9. PHP字符串中的变量解析(+教你如何在PHP字符串中加入变量)

    定义字符串的时候,用单引号或者双引号都是可以的.我个人习惯是用双引号.在输出字符串的时候,若字符串中含有字符串变量,使用单引号和双引号则是有区别的.如下面程序: 1 2 3 4 5 6 7 8 < ...

随机推荐

  1. webpack的require.context()实现路由“去中心化”管理

    最近在开发一个大型vue单页面应用的时候,项目最初是将所有的路由写在一个router.js的文件里. const router = new Router({ mode: "history&q ...

  2. pyppepeer淘宝登录

    代码: import time import random import asyncio import pyppeteer class LoginTaoBao: """ ...

  3. 小白学 Python 数据分析(16):Matplotlib(一)坐标系

    人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...

  4. css报模块没找到 分析思路 从后往前找,先定位最后blue.less 解决:iview升级4.0 css没改导致编译不过去

    E:\xxx\xxx\xxx\../../../../../../../E:/xxx/xxx/xxx/node_modules/_iview@3.5.4@iview/src/styles/common ...

  5. Java注解 看这一篇就够了

    注解 1.概念 注解:说明程序的.给计算机看的 注释:用文字描述程序的.给程序员看的 注解的定义:注解(Annotation),也叫元数据.一种代码级别的说明.它是JDK1.5及以后版本引入的一个特性 ...

  6. 小程序中内容审核功能的使用(后台使用thinkPHP5.1)

    本文包含文本和图片的检测 //接收要检测的文本内容并调用检测方法 public function textCheck(Request $request){ //内容安全识别 $data['conten ...

  7. tars之springboot的初步使用

    公司要求使用tars框架,现学习的,听老大讲的经验和看的一些技术博客,感觉和SpringCloud有些相似,不过内部有自己的规范,基于rpc实现的服务与服务之间的远程调用,而cloud的远程调用是基于 ...

  8. 从一个小例子引发的Java内存可见性的简单思考和猜想以及DCL单例模式中的volatile的核心作用

    环境 OS Win10 CPU 4核8线程 IDE IntelliJ IDEA 2019.3 JDK 1.8 -server模式 场景 最初的代码 一个线程A根据flag的值执行死循环,另一个线程B只 ...

  9. 理解Go语言组件flag

    作用 主要用来实现命令行的参数解析,以达到实现以下效果的目的 $ cmd -flagname 123 使用方式 flag是Go语言的内置包,能接收的参数类型主要有字符串.布尔和数值类型. 方式一 fu ...

  10. Oracle 中文日期转换

    中文日期转换 select to_char(to_date('07-5月-17'),'yyyy-MM-dd HH24:mi:ss') from dual