You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在数组循环中正确使用async/await?求最优非阻塞实现方案

遍历数组执行异步任务的正确姿势

你当前forEach写法的问题

你现在用forEach搭配async回调的写法存在隐患:

  • forEach不会处理异步函数返回的Promise,外层的async函数没法await所有循环里的异步任务完成,这些任务相当于“启动后不管”,你无法知道它们何时全部结束
  • 如果某个异步操作抛出错误,外层的try/catch(如果存在)根本捕获不到,因为每个async回调都是独立的Promise实例
  • 虽然你加了await wait(i * 300),但这只是让单个任务内部延迟,所有异步任务还是会被同时启动,并非真正的顺序执行

非阻塞并行执行:Promise.all + map(最优方案)

如果你的需求是尽可能快地完成所有异步任务(非阻塞、并行发起请求),Promise.all搭配map就是最优解。map会把数组每个元素转换成Promise,Promise.all会等待所有Promise完成,外层async函数可以await整个过程,还能统一处理错误。

修改你的代码如下:

if (neighboursArr) {
  // 用map将每个元素转换为异步任务的Promise
  const neighbourPromises = neighboursArr.map(async (el, i) => {
    await wait(i * 300); // 不需要延迟可直接删除该行
    const neighbourRes = await fetch(`https://restcountries.com/v3.1/alpha/${el}`);
    const neighbourData = await neighbourRes.json();
    return neighbourData[0];
  });

  // 等待所有异步任务完成
  const allNeighbourData = await Promise.all(neighbourPromises);
  
  // 统一渲染结果(也可以在map里直接渲染,不影响并行逻辑)
  allNeighbourData.forEach(data => renderCountry(data, "neighbour"));
} else {
  renderMessage("It is lonely island :)");
}

如果担心单个请求失败导致整个Promise.all失败,可以改用Promise.allSettled,它会返回所有Promise的执行结果(成功或失败),你可以自行过滤处理。

顺序执行(阻塞式,按顺序完成)

如果你的需求是必须等前一个异步任务完成,再执行下一个,那用for...of循环最稳妥,它天然支持await:

if (neighboursArr) {
  for (const [i, el] of neighboursArr.entries()) {
    await wait(i * 300);
    const neighbourRes = await fetch(`https://restcountries.com/v3.1/alpha/${el}`);
    const neighbourData = await neighbourRes.json();
    renderCountry(neighbourData[0], "neighbour");
  }
} else {
  renderMessage("It is lonely island :)");
}

这个写法会严格按照数组顺序执行,每个任务完成后才会进行下一个,外层async函数可以await整个循环过程。

内容的提问来源于stack exchange,提问作者Wick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 16:37:12