如何串行或者并行运行异步循环?

在使用循环处理异步的魔法之前,我们先来看下我们是怎么处理同步循环的。

同步循环

很久以前我写的循环是这样的:

for (var i = 0; i < array.length; i++) {
var item = array[i];
// do something with item
}

后来 JavaScript 提供了很多新的特性,现在我们会更倾向于用下面这种写法:

array.forEach((item) => {
// do something with item
})

在开发过程可能会有这么一种需求,我们需要在循环中异步处理 item,那么可以怎么做呢?

异步循环

如何在循环中使用 await?我们试着写一个异步函数,然后 await 每一次循环任务。

async function processArray(array) {
array.forEach(() => {
// define synchronous anonymous function
// it will throw error here
await func(item)
});
}

这个代码会抛出一个错误,因为我们不能在同步方法中使用 await, processArray 确实是异步函数,但是 array.forEach 里的匿名函数是同步的。

1. 不要等待结果

要处理这个问题,我们可以把这个匿名函数定义为异步的:

async function processArray(array) {
array.forEach(() => {
await delayedLog(item)
});
console.log('Done!');
}

但是这样的话 forEach 方法就相当于异步的了,不会等待遍历完所有的 item,例如下面这段代码:

function delay () {
return new Promise(resolve => setTimeout(resolve, 300));
} async function delayedLog(item) {
// notice that we can await a function that returns promise
await delay();
// log item only after a delay
console.log(item);
} async function processArray(array) {
array.forEach(() => {
await delayedLog(item)
});
console.log('Done!');
} processArray([1, 2, 3]);

将会输出:

Done!
1
2
3

如果你不需要等待这个循环完成,这样就已经可以了。但是大部分情况我们还是需要等待这个循环完成才进行之后的操作。

2. 串行遍历

要等待所有的结果返回,我们还是要回到老式的 for 循环写法:

async function processArray(array) {
for (const item of arr) {
await delayedLog(item);
}
console.log('Done!');
}

最后的结果符合我们的预期:

1
2
3
Done!

上面这段的遍历代码是串行执行的,我们也可以把它换成并行的。

3. 并行遍历

我们可以稍微更改上面的代码来编程并行的:

async function processArray(array) {
// map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
// async 修饰的方法返回值是一个promise对象,因此下面map的返回值就是一个promise列表
const promiseArr = array.map(delayedLog);
// wait until all promises are resolved
await Promise.all(promiseArr);
console.log('Done!');
}

(注意:对于特别大的数组不建议使用这种写法,太多的并行任务会加重 CPU 和内存的负荷)

转自:https://zhuanlan.zhihu.com/p/31000936

JavaScript 循环:如何处理 async/await的更多相关文章

  1. JavaScript异步编程——Async/Await vs Promise

    兼容性 提醒一下各位,Node 现在从版本 7.6 开始就支持 async/await 了.而就在前几天,Node 8已经正式发布了,你可以放心地使用它. 如果你还没有试过它,这里有一堆带有示例的理由 ...

  2. 20分钟带你掌握JavaScript Promise和 Async/Await

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://www.freecodecamp.org/news/learn-promise-a ...

  3. Javascript中的async await

    async / await是Javascript是ES7的重要特性之一,也是目前社区里公认的优秀异步解决方案.目前,async / await这个特性已经是stage 3的建议,可以看看TC39的进度 ...

  4. javascript异步编程 Async/await

    Async/await Async/await 在学习他之前应当补充一定的 promise 知识 它是一种与 promise 相配合的特殊语法,目前被认为是异步编程的终级解决方案 值得我们每一个人学习 ...

  5. JavaScript中的async/await详解

    1.前言 ​ async函数,也就是我们常说的async/await,是在ES2017(ES8)引入的新特性,主要目的是为了简化使用基于Promise的API时所需的语法.async和await关键字 ...

  6. [转] 理解 JavaScript 的 async/await

    [From] https://segmentfault.com/a/1190000007535316      边城 2016年11月19日发布 随着 Node 7 的发布,越来越多的人开始研究据说是 ...

  7. 理解 JavaScript 的 async/await

    随着 Node 7 的发布,越来越多的人开始研究据说是异步编程终级解决方案的 async/await.我第一次看到这组关键字并不是在 JavaScript 语言里,而是在 c# 5.0 的语法中.C# ...

  8. promise async await使用

    1.Promise (名字含义:promise为承诺,表示其他手段无法改变) Promise 对象代表一个异步操作,其不受外界影响,有三种状态: Pending(进行中.未完成的) Resolved( ...

  9. promise 进阶 —— async / await 结合 bluebird

    一.背景 1.Node.js 异步控制 在之前写的 callback vs async.js vs promise vs async / await 里,我介绍了 ES6 的 promise 和 ES ...

随机推荐

  1. MAC快捷方式记录

    刚刚转到MAC,很多功能发现不能用,总结一下: 刷新页面:command+r 命令行,到行首:control+a 命令行,到行尾:control+e vim,到行尾:shift+$ vim,到行首:s ...

  2. stingray 页面布局与设计

    前言 前面我们已经了解了系统中的HTML组件,现在我们就可以开始用这些组件来设计页面了,他们就像是一块块小积木,我们要盖起高楼大厦. 两种页面容器组件 我们将关联性较强的多个HTML组件放到一个容器组 ...

  3. 如何处理Android中的防缓冲区溢出技术

    [51CTO专稿]本文将具体介绍Android中的防缓冲区溢出技术的来龙去脉. 1.什么是ASLR? ASLR(Address space layout randomization)是一种针对缓冲区溢 ...

  4. Run Test Case on Spark

        今天有哥们问到怎样对Spark进行单元測试.如今将Sbt的測试方法写出来,例如以下:     对Spark的test case进行測试的时候能够用sbt的test命令:     一.測试所有t ...

  5. Python实践摘录

    1:中文编码问题 Python语言默认不识别UTF-8的编码字符串,所以当文件中有中文并且是以UTF-8编码时,需要在python文件头部加一行注释,指明识别utf-8编码. # coding=utf ...

  6. Java类中代码的执行顺序 静态代码块>构造代码块>构造方法

    一:静态代码块 注意是代码块,不是静态函数.函数要调用才执行,代码块加载就执行,一般是静态变量的声明与初始化.被static修饰的代码块(赋值.输出操作等).类中静态语句块仅在类加载时被执行一次 如 ...

  7. python 排序 sorted 如果第一个条件 相同 则按第二个条件排序

    怎样遍历一个list 符合下列条件 1. 按照元组的第一个从小到大排序 2. 如果第一个相同 则按照元组第2个从大到小 排序 a = [[2,3],[4,1],(2,8),(2,1),(3,4)] b ...

  8. Dubbo OPS工具——dubbo-admin & dubbo-monitor

    1. 前言 今年八月份的时候,查看github仓库,Dubbo OPS还提供了三种工具用于Dubbo的监控运维: 九月份,伴随着Dubbo的全面快速的升级,现在仓库里Dubbo OPS下这三个工具已经 ...

  9. Easyui + asp.net MVC 系列教程 第19-23 节 完成注销 登录限制过滤 添加用户

    前面视频 文章地址 Easyui + asp.net MVC 系列教程 第09-17 节 完成登录 高清录制  Easyui + asp.net mvc + sqlite 开发教程(录屏)适合入门  ...

  10. shell脚本逐个杀死k8s中某个应用的pod

    #!/bin/bash pod01=`kubectl get pod -o wide -n weifeng-system|grep official-ui-node-prod|awk -F : 'NR ...