首页 > 其他分享 >如何在forEach内使用异步调用 async/await

如何在forEach内使用异步调用 async/await

时间:2023-01-05 16:01:47浏览次数:55  
标签:const users await user async details forEach

翻自: How to use async and await in a forEach JS loop?
https://learn.coderslang.com/0144-how-to-use-async-and-await-in-a-foreach-js-loop/

事实上我们无法在 forEach 循环内使用 async/await 起到异步作用,让我们看看如何解决修复它。

async/await 在forEach 中为啥不起作用?

当你在forEach 循环内调用异步函数,下一个循环并不会等到上个循环结果后再被调用

想象一下,你有一个 getUsers 方法返回用户列表 User , user只有用户列表,但不包含具体的detail信息,所以你使用forEach 试图去获取用户详情

const users = await getUsers();

users.forEach(user => {
  const details = user.getDetails();
  console.log(details);
})

打印结果却是 3 个pending状态的 promise

你很自然的想到getDetails是个异步函数,需要给它加上await 关键字

const users = await getUsers();

users.forEach(user => {
  const details = await user.getDetails();
  console.log(details);
})

运行后发现报了另一个语法错误

SyntaxError: await is only valid in async function

你意识到给如果 forEach 传递的函数有是异步 则需要用 async 标记为异步函数

再次修复它

const users = await getUsers();

users.forEach(async (user) => {
  const details = await user.getDetails();
  console.log(details);
})

很好,你盯着半天发现并没有按users数组的顺序输出结果

解决方案:

你需要使用for 代替 forEach 循环重写这部分代码

const users = await getUsers();

for (let i = 0; i < users.length; i++) {
  const details = await user.getDetails();
  console.log(details);
}

也可以使用 for .... of

const users = await getUsers();

for (const user of users) {
  const details = await user.getDetails();
  console.log(details);
}

如果你实在不喜欢简单的代码,那么可以用个小技巧 使用 Array 的 map 方法

const users = await getUsers();

const userDetailsPromises = users.map(user => user.getDetails());
const userDetails = await Promise.all(userDetailsPromises);

console.log(userDetails);

让我们一步步分析
1、第一行代码没有改变就是获取 users 数组
2、使用map循环调用 getDetails 返回新的 userDetailsPromises 数组,数组元素都为Promise类型
3、使用 await Promise.all 等待所有 Promise 处理完毕
4、最后打印出结果数组

代码也可以组合简化为

const userDetails = await Promise.all(users.map(user => user.getDetails()));

标签:const,users,await,user,async,details,forEach
From: https://www.cnblogs.com/willian/p/17027811.html

相关文章

  • Spring Boot中@Async的作用
    importorg.springframework.context.annotation.AnnotationConfigApplicationContext;importorg.springframework.context.annotation.Bean;importorg.springframewo......
  • @Async异步注解的使用
    @Async简介使用spring快速开启异步执行服务的注解应用场景同步:同步就是整个处理过程顺序执行,当各个过程都执行完毕,并返回结果。异步:异步调用则是只是发送了调用的指......
  • 分析.foreach和.map的区别
    在程序员编程的过程中经常会有遍历数组的需要,.foreach和.map都具有遍历的作用,那么他们的共同点和区别是什么呢?我们来分析一下.一、共同点1.都只能遍历数组。2.每次......
  • foreach-2023-1-2
    for循环条件语句中的这个(intnum:nums)是什么意思?foreach语句是java5的新特征之一,在遍历数组、集合方面,foreach为开发人员提供了极大的方便。foreach语句是for语句的特殊简......
  • 迭代(遍历数组)forEach
    1.forEach用法vararr=[13,2,2,5] varsum=0 //forEach用法:Array.forEach(function(数组当前项的值,数组当前项的索引值,数组本身){}) arr.forEach(function(valu......
  • SpringBoot - 异步任务 @EnableAsync,@Async
    1.在启动类上添加@EnabnleAsync注解开启对异步任务的支持//开启对异步任务的支持@EnableAsync@SpringBootApplicationpublicclassLearn20221218Application{p......
  • 使用Python的asyncio模块异步下载整站壁纸
    这篇文章主要给大家介绍关于Python中asyncio模块的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Python具有一定的参考学习价值,需要的朋友们下面来一起学习学......
  • Generator(生成器),入门初基,Coroutine(原生协程),登峰造极,Python3.10并发异步编程as
    普遍意义上讲,生成器是一种特殊的迭代器,它可以在执行过程中暂停并在恢复执行时保留它的状态。而协程,则可以让一个函数在执行过程中暂停并在恢复执行时保留它的状态,在Python3......
  • babel的使用(关于使用async报错的问题)
    一、配置文件.babelrc.babelrc文件存放在项目的根目录下。{"presets":[],"plugins":[]}presets字段设定转码规则,你可以根据需要安装。$npmin......
  • ReentrantLock Condition await signal 专题
     Condition的执行方式,是当在线程T1中调用await方法后,线程T1将释放锁,并且将自己阻塞,等待唤醒,线程T2获取到锁后,开始做事,完毕后,调用Condition的signal方法,唤醒线程T1,在t2执行......