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

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

同步循环

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

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

node Later定时任务的更多相关文章

  1. node编写定时任务,for循环只执行一遍的解决办法

    在用node编写定时任务时候,发现for循环只执行i=0这一次,就不接着循环执行了,下面贴上代码: exports.task = async function(ctx){ let { app } = ...

  2. node.js定时任务 node-schedule

    先安装 node-schedule npm install node-schedule //1:确定时间 //例如:2014年2月14日,15:40执行 var schedule = require( ...

  3. node.js定时任务:node-schedule的使用

    安装 npm install node-schedule 使用方法 1:确定时间 例如:2014年2月14日,15:40执行 var schedule = require("node-sch ...

  4. babeljs源码

    babel.min.js!function(e,t){"object"==typeof exports&&"object"==typeof mo ...

  5. node定时任务——node-schedule模块使用说明

    在实际开发项目中,会遇到很多定时任务的工作.比如:定时导出某些数据.定时发送消息或邮件给用户.定时备份什么类型的文件等等. 一般可以写个定时器,来完成相应的需求,在node.js中自已实现也非常容易, ...

  6. PHP定时任务实现(计划任务 vs node.js)

    PHP自动任务(单线程) 一.计划任务实现 :最终需要在服务器(windows)上 设置计划任务 1.写好php任务文件 auto.php:链接数据库 判断条件操作数据库 2.创建bat文件 例:ru ...

  7. 【重学Node.js 第4篇】实现一个简易爬虫&启动定时任务

    实现一个简易爬虫&启动定时任务 课程介绍看这里:https://www.cnblogs.com/zhangran/p/11963616.html 项目github地址:https://gith ...

  8. node.js中使用node-schedule实现定时任务

    摘要:有时我们需要在每天的固定时间执行某个脚本,或者在某个固定时间执行某个任务.NodeJS中的 node-schedule 可以很好的实现定时任务. 1.安装 npm install node-sc ...

  9. node中的定时任务

    node-schedule每次都是通过新建一个scheduleJob对象来执行具体方法. 时间数值按下表表示 * * * * * * ┬ ┬ ┬ ┬ ┬ ┬ │ │ │ │ │ | │ │ │ │ │ ...

随机推荐

  1. Redis介绍以及安装(Linux与windows)

    1.liunux系统 redis是当前比较热门的NOSQL系统之一,它是一个key-value存储系统.和Memcached类似,但很大程度补偿了memcached的 不足,它支持存储的value类型 ...

  2. Swift语言简介+快速上手

    相关: Xcode 6 beta:https://developer.apple.com/xcode/downloads/ swift语言学习文档英文版:http://pan.baidu.com/s/ ...

  3. Java-Java中System.arraycopy() 和 Arrays.copyOf()两者之间的区别

    如果我们想拷贝一个数组,我们可能会使用System.arraycopy()或者Arrays.copyof()两种方式.在这里,我们将使用一个比较简单的示例来阐述两者之间的区别. 1.示例代码: Sys ...

  4. <转>键盘扫描码

    原文链接:http://www.cnblogs.com/wqw/archive/2009/08/30/1556618.html //以下是一个检测按键扫描码的程序 #i nclude <bios ...

  5. 最长不下降子序列 O(nlogn) || 记忆化搜索

    #include<stdio.h> ] , temp[] ; int n , top ; int binary_search (int x) { ; int last = top ; in ...

  6. docker commit容器

    docker commit 容器ID 镜象REPOSITORY 镜象TAG 如docker commit 52b41c68ac7b registry.lenovows.com:5000/video-a ...

  7. java笔记--使用事件分配线程更新Swing控件

    使用事件分配线程更新Swing控件: Swing并不是线程安全的,如果在多个线程中更新Swing控件,则很可能造成程序崩溃. 为了避免这种问题,可以使用时间分配线程来更新Swing控件. EventQ ...

  8. 在mac上安装nodejs

    文章转载自我的个人博客  www.iwangzheng.com node.js最初是2009年发布的,目标是为聊实现事件驱动和非阻塞I/O的web服务器,应用的场景非常的广泛,有web服务器.实时应用 ...

  9. k Sum | & ||

    k Sum Given n distinct positive integers, integer k (k <= n) and a number target. Find k numbers ...

  10. 解决Cannot change version of project facet Dynamic web module to 3.0

    我们用Eclipse创建Maven结构的web项目的时候选择了Artifact Id为maven-artchetype-webapp,由于这个catalog比较老,用的servlet还是2.3的,而一 ...