forEach里用await的坑

forEach和await组合使用

const userIds = [1, 2, 3];

async function updateUserStatus(id) {
 console.log(`开始更新用户${id}`);
 // 模拟一个需要 1 秒的网络请求
 await new Promise(resolve => setTimeout(resolve, 1000)); 
 console.log(`用户 ${id} 更新成功!`);
 return { success: true };
}

async function batchUpdateUsers(ids) {
 console.log("1.开始批量更新");

  ids.forEach(async (id) => {
    await updateUserStatus(id);
  });

 console.log("2.所有用户更新完毕!"); // 问题的根源在这里!
}

batchUpdateUsers(userIds);

输出结果:

1.开始批量更新
2.所有用户更新完毕!
开始更新用户1
开始更新用户2
开始更新用户3
// 等待约1秒后
用户1更新成功!
用户2更新成功!
用户3更新成功!

推荐方案一:for...of循环(顺序执行)

async function batchUpdateUsersInOrder(ids) {
  console.log("开始批量更新 (顺序执行) ");

  for (const id of ids) {
    // 这里的 await 会实实在在地暂停 for 循环的下一次迭代
    await updateUserStatus(id); 
  }

  console.log("所有用户更新完毕!");
}

推荐方案二:Promise.all+ map(并行执行)

async function batchUpdateUsersInParallel(ids) {
 console.log("开始批量更新 (并行执行) ");

 // 1. map 会立即返回一个 Promise 数组
 const promises = ids.map(id => updateUserStatus(id));

 // 2. Promise.all 会等待所有 promises 完成
 await Promise.all(promises);

 console.log("所有用户更新完毕!(这次是真的,而且很快) ");
}

推荐方案三:for循环或for...in循环(更灵活的)

// 传统 for 循环
for (let i = 0; i < ids.length; i++) {
  await updateUserStatus(ids[i]);
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • js遍历数组常用基本就是 map,reduce,forEach,for...of map 针对是返回值处理情况,关...
    pruple_Boy阅读 3,301评论 0 0
  • 1、项目中亮点(难点) 在项目中用ECharts画的可视化大屏的时候,里面的字体在调整浏览器大小的时候无法做到适配...
    f360f8fc4fbb阅读 968评论 0 0
  • 0 HTML5相关 websocket WebSocket 使用ws或wss协议,Websocket是一个持久化的...
    可爱多小姐阅读 4,411评论 0 0
  • 原型链的理解 看一个实例 原型和原型链首先要知道几个概念:在js里,继承机制是原型继承。继承的起点是 对象的原型(...
    __bomb__阅读 994评论 0 0
  • 22. 如何判断一个对象是否属于某个类? ●第一种方式,使用 instanceof 运算符来判断构造函数的 pro...
    稚沅阅读 949评论 0 0