JavaScript 循环:如何处理 async/await
如何串行或者并行运行异步循环?
在使用循环处理异步的魔法之前,我们先来看下我们是怎么处理同步循环的。
同步循环
很久以前我写的循环是这样的:
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的更多相关文章
- JavaScript异步编程——Async/Await vs Promise
兼容性 提醒一下各位,Node 现在从版本 7.6 开始就支持 async/await 了.而就在前几天,Node 8已经正式发布了,你可以放心地使用它. 如果你还没有试过它,这里有一堆带有示例的理由 ...
- 20分钟带你掌握JavaScript Promise和 Async/Await
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://www.freecodecamp.org/news/learn-promise-a ...
- Javascript中的async await
async / await是Javascript是ES7的重要特性之一,也是目前社区里公认的优秀异步解决方案.目前,async / await这个特性已经是stage 3的建议,可以看看TC39的进度 ...
- javascript异步编程 Async/await
Async/await Async/await 在学习他之前应当补充一定的 promise 知识 它是一种与 promise 相配合的特殊语法,目前被认为是异步编程的终级解决方案 值得我们每一个人学习 ...
- JavaScript中的async/await详解
1.前言 async函数,也就是我们常说的async/await,是在ES2017(ES8)引入的新特性,主要目的是为了简化使用基于Promise的API时所需的语法.async和await关键字 ...
- [转] 理解 JavaScript 的 async/await
[From] https://segmentfault.com/a/1190000007535316 边城 2016年11月19日发布 随着 Node 7 的发布,越来越多的人开始研究据说是 ...
- 理解 JavaScript 的 async/await
随着 Node 7 的发布,越来越多的人开始研究据说是异步编程终级解决方案的 async/await.我第一次看到这组关键字并不是在 JavaScript 语言里,而是在 c# 5.0 的语法中.C# ...
- promise async await使用
1.Promise (名字含义:promise为承诺,表示其他手段无法改变) Promise 对象代表一个异步操作,其不受外界影响,有三种状态: Pending(进行中.未完成的) Resolved( ...
- promise 进阶 —— async / await 结合 bluebird
一.背景 1.Node.js 异步控制 在之前写的 callback vs async.js vs promise vs async / await 里,我介绍了 ES6 的 promise 和 ES ...
随机推荐
- JDK5.0特性-线程 Callable和Future
来自:http://www.cnblogs.com/taven/archive/2011/12/17/2291466.html import java.util.concurrent.Callable ...
- 使用SpringBoot创建Web项目
1.pom.xml 引入 <parent> <groupId>org.springframework.boot</groupId> <artifactId&g ...
- css 进度条
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...
- ibatis 批量更新(二)
1.情景展示 oracle数据库中,需要根据指定字段内容调用加密程序后,根据主键id进行更新其对应的字段mindex_id的值: 加密通过Java实现,然后通过Java对其进行更新: Java使用 ...
- VTK中模型的旋转与平移
当从外界读入STL等三维模型时,其会按照它内部的坐标位置进行显示.因此它的位置和大小是确定的.但是在实际应用中,有可能需要人为地对这个模型在空间中进行旋转.平移或缩放等操作.VTK中有许多和旋转.平移 ...
- Spring Aspect实现AOP切面
百度搜索的大部分的文章(demo)都只是对简单的方法进行切面(例如:public String say(String name)),却未介绍在入参是不固定的时候改怎么处理,后来查到可以使用org.as ...
- java第五节 多线程/多线程的同步
/* 第五讲 多线程 了解进程和线程 在多任务系统中,每个独立执行的程序称为进程,也就是"正在进行的程序",我们现在使用的操作系统一般都是多任务的 即能够同时执行多个应用程序,实际 ...
- 初始建库SGA该设多大、PGA该设多大的建议
1.背景情况 非常多新业务系统上线,大部分DBA也不懂业务.就闷着头建库,SGA值设多大,PGA设多大,随便指定一个值就得了,执行一段时间后,或许就由于这个值是随便指定的.比如SGA+PGA大于总物理 ...
- HBase Go客户端Row构造注意事项
1. Hbase 的Go客户端语言使用方法 2. Hbase的Row使用注意事项 2.1. Row的前几个字段尽量散列 2.2. Row的排序是把所有Row中的字符做字典排序 我们最近在一个项目中使用 ...
- 使用Idea添加PYTHONPATH的一种方案
工作中我们常常需要更改PYTHONPATH,为项目添加一些依赖. 而不同的项目依赖的PYTHONPATH是不一样的,这就导致项目之间的PYTHONPATH发生混乱. 另一方面,有的电脑上PYTHON2 ...