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

Node.js中async fetch函数外获取存储数组及forEach场景异常问题

问题原因

  1. 最初的代码中,fetchFromApi是异步函数,调用后会立即返回Promise,不会阻塞后续代码执行。调用后立刻打印failed时,fetch请求还未完成,往数组中插入值的逻辑还未触发,所以得到空数组。
  2. 加入forEach后的问题,核心原因是*Array.prototype.forEach不支持等待异步回调执行完成*:你给forEach传入的async回调会被逐个启动,但forEach不会等待这些异步任务的Promise状态变更,遍历完成就直接结束函数。所以你写的await fetchFromApi(j)实际没有等待内部所有fetch请求执行完成,返回failed时所有请求还在运行中,自然还是空数组。

解决方案

提供两种常用的实现方案,可根据场景选择:

方案1:用for...of替代forEach(串行请求,可控并发)

for...of原生支持异步等待,会按顺序等待每个请求完成后再执行下一个,适合需要控制请求并发、避免触发接口限流的场景:

const myFunction = async (j) => {  
  // 建议声明为局部变量,避免污染全局作用域
  const failed = [];
  async function fetchFromApi(i) {
      const ApiEndpoint = "https://jsonplaceholder.typicode.com/todos/" + i
      const httpRequest = { method: "GET" }
      const response = await fetch(ApiEndpoint, httpRequest);
      if (!response.ok) {
          failed.push(i);
      } else {
          const symbolData = await response.json();
          console.log(JSON.stringify(symbolData))
          return JSON.stringify(symbolData);
      }
  };

  // 遍历等待每个请求执行完成
  for (const item of j) {
    await fetchFromApi(item)
  }
  return failed
}

myFunction(["aaa", "abc"]).then(data=>console.log(data))

方案2:用Promise.all批量处理(并行请求,性能更高)

所有请求同时发起,等待全部请求完成后再统一处理结果,适合请求量不大、不需要控制并发的场景,运行速度更快:

const myFunction = async (j) => {  
  async function fetchFromApi(i) {
      const ApiEndpoint = "https://jsonplaceholder.typicode.com/todos/" + i
      const httpRequest = { method: "GET" }
      try {
        const response = await fetch(ApiEndpoint, httpRequest);
        if (!response.ok) {
            // 失败直接返回请求参数作为标识
            return { type: 'fail', data: i }
        } else {
            const symbolData = await response.json();
            console.log(JSON.stringify(symbolData))
            return { type: 'success', data: JSON.stringify(symbolData) }
        }
      } catch (e) {
        // 额外捕获网络异常等报错
        return { type: 'fail', data: i }
      }
  };

  // 并行启动所有请求,等待全部执行完成
  const results = await Promise.all(j.map(item => fetchFromApi(item)))
  // 过滤出所有失败的项得到failed数组
  const failed = results.filter(item => item.type === 'fail').map(item => item.data)
  return failed
}

myFunction(["aaa", "abc"]).then(data=>console.log(data))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 15:06:07