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

Node.js无法返回完整对象数组仅返回首个元素问题求助

问题分析与解决方案

嗨,我来帮你捋捋这个问题的核心原因:你没处理好异步操作的执行顺序。

为什么原来的代码会出问题?

  • 循环里的每个fetch都是异步操作,它们的.then回调会在请求完成后才执行,但循环本身是同步执行的——它会一口气发起所有请求,但不会等任何一个请求完成。
  • 当你把res.send写在内部的.then里时,第一个请求完成后就立刻发送了响应,这时候其他请求还在处理中,hackerArr里只有第一个元素,所以接口返回的就是它。
  • 如果你把res.send移到循环外面,循环执行完后立刻就会执行res.send,但这时候所有fetch请求都还没完成,hackerArr还是空数组,自然返回空。

修复方案:用Promise.all等待所有异步请求完成

我们可以把所有fetch请求的Promise收集起来,用Promise.all等待它们全部完成后,再统一处理结果并发送响应。这里给你两种写法:

写法1:基于Promise链式调用的版本

export default (req, res) => {
  if (req.method === 'POST') {
    // 获取文章编号数组
    fetch(req.body.url, {
      method: "GET",
      headers: { "Content-Type": "application/json" }
    })
    .then(response => response.json())
    .then(data => {
      // 收集所有fetch请求的Promise
      const fetchPromises = [];
      for (let i = 0; i < req.body.count; i++) {
        const promise = fetch(`https://hacker-news.firebaseio.com/v0/item/${data[i]}.json`, {
          method: "GET",
          headers: { "Content-Type": "application/json" }
        })
        .then(response => response.json());
        fetchPromises.push(promise);
      }
      // 等待所有请求完成
      return Promise.all(fetchPromises);
    })
    .then(hackerArr => {
      // 所有请求都完成了,现在返回完整数组
      res.setHeader('Content-Type', 'application/json');
      res.send(JSON.stringify({ response: hackerArr }));
    })
    .catch(err => {
      console.log(err);
      res.status(500).send(JSON.stringify({ error: 'Request failed' }));
    });
  } else {
    res.setHeader('Content-Type', 'application/json');
    res.end(JSON.stringify({ response: 'Invalid Request Method' }));
  }
}

写法2:用async/await简化代码(更推荐,可读性更强)

export default async (req, res) => {
  if (req.method === 'POST') {
    try {
      // 获取文章编号数组
      const idResponse = await fetch(req.body.url, {
        method: "GET",
        headers: { "Content-Type": "application/json" }
      });
      const idData = await idResponse.json();

      // 收集所有请求的Promise
      const fetchPromises = [];
      for (let i = 0; i < req.body.count; i++) {
        fetchPromises.push(
          fetch(`https://hacker-news.firebaseio.com/v0/item/${idData[i]}.json`, {
            method: "GET",
            headers: { "Content-Type": "application/json" }
          }).then(res => res.json())
        );
      }

      // 等待所有请求完成,得到完整数组
      const hackerArr = await Promise.all(fetchPromises);

      // 返回响应
      res.setHeader('Content-Type', 'application/json');
      res.send(JSON.stringify({ response: hackerArr }));
    } catch (err) {
      console.log(err);
      res.status(500).send(JSON.stringify({ error: 'Request failed' }));
    }
  } else {
    res.setHeader('Content-Type', 'application/json');
    res.end(JSON.stringify({ response: 'Invalid Request Method' }));
  }
}

额外提示

  • 记得加上错误处理,避免因为某个请求失败导致整个接口挂掉。
  • Promise.all会在所有Promise都resolve后返回结果数组,顺序和你传入的Promise顺序一致,刚好对应你要的文章顺序。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 06:27:37