Node.js中forEach循环调用API后返回空数组的问题求助
解决request异步请求导致返回空数组的问题
问题原因
- getVuln函数无有效返回值:getVuln内部使用request的回调模式,回调里的
return body不会作为函数的返回值,函数本身没有return语句,调用getVuln(prct)得到的是undefined,最终finalData里的元素会被JSON序列化为null。 - 异步请求未等待完成就返回结果:
forEach是同步遍历,遍历过程中发起异步请求,但不会等待所有请求完成就执行res.send,此时finalData还未被填充实际响应数据。
解决方案
通过Promise封装request,结合async/await和Promise.all处理异步流程,确保所有请求完成后再返回结果:
1. 封装request为Promise函数
将回调式的request转换为Promise,方便用async/await管理异步操作:
const request = require('request'); // 封装request为Promise function requestPromise(options) { return new Promise((resolve, reject) => { request(options, (err, httpResponse, body) => { if (err) { reject(err); } else { resolve(body); } }); }); }
2. 修改路由逻辑,用async/await处理异步流程
const options = { json: true, // 注意request库的配置选项是小写json,原代码大写JSON会失效 method: 'POST', headers: { 'Content-Type': 'application/json; charset=UTF-8', "Authorization": process.env.authID, }, body: {}, uri:'' }; app.post('/vuln/sync', async (req, res) => { try { // 调用第一个API获取项目数组 const getProject = Object.assign({}, options); getProject.uri = 'first API'; getProject.body = {}; const projectData = await requestPromise(getProject); // 生成所有第二个API的请求Promise const vulnPromises = projectData.projects.map(prct => { const getSecondApi = Object.assign({}, options); getSecondApi.body = {}; getSecondApi.uri = `second API${prct.id}/XYZ`; return requestPromise(getSecondApi); }); // 等待所有第二个API请求完成,收集结果 const finalData = await Promise.all(vulnPromises); res.send({ message: finalData }); } catch (err) { console.error(err); return res.status(500).send(err); } });
关键注意点
- 原代码中的
JSON: true需改为json: true,request库仅识别小写的json配置,否则无法自动将响应解析为JSON对象。 - 使用
map替代forEach生成Promise数组,再通过Promise.all等待所有异步请求完成,确保返回数据时所有响应都已获取。 - 路由处理函数添加
async关键字,内部用await等待异步操作,避免回调嵌套和时序错误。
内容的提问来源于stack exchange,提问作者santosh
相关产品推荐
相关产品推荐

