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

NodeJS中request.get异步请求结果无法存入数组问题求助

问题根源:异步操作的执行顺序

嘿,这个问题我太熟了——你踩中了Node.js异步编程的经典坑!核心问题在于request.get是异步函数,它不会等请求完成再继续执行后面的代码。

咱们拆解下你代码的执行顺序,就能明白为啥resp总是undefined:

  1. 你初始化了数组、request模块和结果数组
  2. 进入forEach循环,对第一个URL:
    • 声明了resp变量(初始值就是undefined)
    • 调用request.get发起HTTP请求——这一步是后台跑的,不会阻塞代码
    • 立刻执行msresult.push(resp),这时候请求还没完成,resp当然还是undefined
  3. 第二个URL重复同样的操作
  4. 马上执行console.log(msresult),此时两个请求都还在后台跑,数组里全是undefined
  5. 等过了一会儿,HTTP请求完成,回调函数才会触发给resp赋值,但这时候早就执行完push和console了,根本没意义

解决方案1:用Promise + async/await(最直观的现代写法)

咱们把异步请求封装成Promise,再用async/await让代码看起来像同步一样执行,这样就能确保拿到结果再push:

const msurls = ["http://example.org/get1", "http://example.org/get2"];
const request = require("request");

// 把request.get包装成返回Promise的函数
function fetchUrl(url) {
  return new Promise((resolve, reject) => {
    request.get(url, (error, response, body) => {
      if (error) {
        reject(error); // 请求失败就抛出错误
      } else {
        resolve(body); // 请求成功就返回body
      }
    });
  });
}

// 用async函数处理异步逻辑
async function getResults() {
  const msresult = [];
  // 用for...of代替forEach,因为forEach不支持await
  for (const msurl of msurls) {
    try {
      const body = await fetchUrl(msurl); // 等待请求完成
      msresult.push(body); // 拿到结果再push
    } catch (error) {
      console.log(`请求${msurl}出错了:`, error);
      msresult.push(null); // 出错时可以存个标记,方便后续处理
    }
  }
  console.log(msresult);
  // 后续处理逻辑就放在这里,比如对msresult做操作
  return msresult;
}

// 调用这个异步函数
getResults();

解决方案2:用Promise.all(并行请求,效率更高)

如果你的两个请求不需要按顺序执行,用Promise.all可以同时发起所有请求,等全部完成后再统一处理,速度会更快:

const msurls = ["http://example.org/get1", "http://example.org/get2"];
const request = require("request");

function fetchUrl(url) {
  return new Promise((resolve, reject) => {
    request.get(url, (error, response, body) => {
      if (error) {
        reject(error);
      } else {
        resolve(body);
      }
    });
  });
}

// 把所有请求转成Promise,然后用Promise.all等待全部完成
Promise.all(msurls.map(url => fetchUrl(url)))
  .then(msresult => {
    console.log(msresult);
    // 后续处理逻辑写在这里
  })
  .catch(error => {
    console.log("有请求失败了:", error);
  });

额外提醒:request库已经废弃啦!

顺便说一句,request库早在2020年就被官方标记为废弃了,不再更新维护。推荐你换成更现代的HTTP客户端,比如axios或者node-fetch,它们本身就支持Promise,写法更简洁:

举个axios的例子:

const msurls = ["http://example.org/get1", "http://example.org/get2"];
const axios = require("axios");

async function getResults() {
  try {
    // 并行发起所有请求,拿到响应数据
    const msresult = await Promise.all(msurls.map(url => axios.get(url).then(res => res.data)));
    console.log(msresult);
    // 后续处理
  } catch (error) {
    console.log("请求出错:", error);
  }
}

getResults();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:26:59