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

JavaScript中如何从Promise调用收集结果?解决数组未填充问题

问题原因

你遇到的问题是异步操作的时序问题:jobs.forEach里的fetch是异步任务,当你执行console.log(successful)时,所有请求还没完成,所以数组是空的。

解决方案

我们可以用Promise.all等待所有job请求完成,再处理结果并排序,下面是两种实现方式:

方式一:使用async/await(更易读)

async function foo() {
    const url = `https://foobar.com`;
    // 获取jobs列表
    const response = await fetch(url, {
        method: 'POST', 
        headers: headers
    });
    const data = await response.json();
    const jobs = data['jobs'];

    // 收集所有job请求的Promise
    const jobPromises = jobs.map(async (job) => {
        const jobUrl = job['url'];
        const jobResponse = await fetch(jobUrl, { headers: headers });
        const jobData = await jobResponse.json();
        // 只返回成功的任务数据
        if (jobData['status'] === 'SUCCESS') {
            return { jobUrl, timeStamp: jobData['timestamp'] };
        }
        return null; // 失败的任务返回null,后续过滤
    });

    // 等待所有请求完成,过滤null值得到成功的任务数组
    let successful = (await Promise.all(jobPromises)).filter(item => item !== null);

    // 基于timestamp排序(如果timestamp是字符串,需要转成Date或数字,这里假设是时间戳数字)
    successful.sort((a, b) => a.timeStamp - b.timeStamp);

    console.log(successful);
}

foo();

方式二:使用Promise链(保持原风格)

function foo() {
    const url = `https://foobar.com`;
    fetch(url, {
        method: 'POST', 
        headers: headers
    }).then(response => response.json())
      .then(data => data['jobs'])
      .then(jobs => {
          // 用map生成所有请求的Promise数组
          const jobPromises = jobs.map(job => {
              const jobUrl = job['url'];
              return fetch(jobUrl, { headers: headers })
                      .then(response => response.json())
                      .then(jobData => {
                          if (jobData['status'] === 'SUCCESS') {
                              return { jobUrl, timeStamp: jobData['timestamp'] };
                          }
                          return null;
                      });
          });
          // 等待所有请求完成后处理
          return Promise.all(jobPromises);
      })
      .then(results => {
          // 过滤失败的任务,得到成功数组
          let successful = results.filter(item => item !== null);
          // 排序
          successful.sort((a, b) => a.timeStamp - b.timeStamp);
          console.log(successful);
      })
      .catch(err => console.error('请求出错:', err)); // 别忘了加错误捕获
}

foo();
关键说明
  • Promise.all会等待所有传入的Promise都完成,才会返回结果数组,这样就能保证我们拿到所有请求的结果后再处理successful数组。
  • 排序时,如果你的timestamp是ISO字符串(比如"2024-05-20T12:00:00Z"),可以把排序逻辑改成:new Date(a.timeStamp) - new Date(b.timeStamp)。
  • 建议加上错误捕获(.catch或try/catch),避免某个请求失败导致整个流程中断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 11:54:22