如何从动态数量的URL获取响应并合并JSON返回结果
解决方案
要解决你的问题,需要处理异步请求的等待和避免响应键名冲突两个核心点,以下是修改后的完整代码及说明:
关键修改点
- 将数据库查询的回调形式改为Promise,配合
async/await实现同步化的异步流程控制 - 使用
Promise.all等待所有请求完成后再统一处理响应 - 提供两种无覆盖的响应合并方案(按需选择)
完整代码
const util = require('util'); // 将databases.find转换为Promise形式(如果是Mongoose等ORM,可直接用databases.find({}).exec()) const findDatabases = util.promisify(databases.find.bind(databases)); app.post('/api/:db/find', async (req, res) => { try { const db = req.params.db; // 等待数据库查询完成,获取所有URL配置 const docs = await findDatabases({}); // 生成所有axios请求的Promise数组 const requestPromises = docs.map(val => { const url = `${val.url}/${db}/findmany`; return axios.post(url, req.body); }); // 等待所有请求完成,拿到所有响应 const responses = await Promise.all(requestPromises); // --- 方案1:将所有响应数据存入数组(无键覆盖问题)--- const mergedResponse = responses.map(response => response.data); res.json(mergedResponse); // --- 方案2:以请求URL为键存储对应响应(便于区分来源)--- // const mergedResponse = {}; // responses.forEach((response, index) => { // const requestUrl = `${docs[index].url}/${db}/findmany`; // mergedResponse[requestUrl] = response.data; // }); // res.json(mergedResponse); } catch (error) { console.log(error); res.json({ success: false }); } });
代码说明
- Promise化数据库查询:解决了原代码中数据库回调与axios异步请求的嵌套问题,让流程更清晰可控
- Promise.all:确保所有请求都完成后再处理响应,避免了原代码中循环内异步请求无法同步结果的问题
- 响应合并方案:
- 方案1适合不需要区分响应来源的场景,直接用数组收集所有结果,完全避免键名冲突
- 方案2通过请求URL作为唯一键,既能保留每个响应的来源信息,也不会出现键值覆盖的情况
内容的提问来源于stack exchange,提问作者Cooper
相关产品推荐
相关产品推荐

