Node.js中如何在单个端点内直接调用多个路由端点
直接调用路由业务逻辑实现聚合响应
核心思路
把每个告警路由里的业务逻辑抽离成独立的异步函数,避免重复代码的同时,让/all-alarms路由可以直接调用这些函数,完全绕开HTTP请求和子进程。
具体实现步骤
1. 抽离业务逻辑到独立函数
原来每个/alarmX路由回调里的核心逻辑,单独封装成可复用的函数,函数接收req作为参数(因为authenticateUser和getSiteIds中间件已经给req注入了用户信息、站点ID等必要数据)。
示例:
// 根据你的实际业务场景调整,这里假设用Express+Mongoose async function getAlarm1Data(req) { // 这里是原/alarm1路由里的业务逻辑 return await AlarmModel.find({ siteId: req.siteIds, type: 'alarm1' }); } async function getAlarm2Data(req) { return await AlarmModel.find({ siteId: req.siteIds, type: 'alarm2' }); } // 同理实现getAlarm3Data、getAlarm4Data
然后修改原告警路由,直接调用这些函数:
router.get('/alarm1', authenticateUser, getSiteIds, async (req, res) => { try { const data = await getAlarm1Data(req); res.json(data); } catch (err) { res.status(500).json({ error: 'Failed to fetch alarm1' }); } }); // 对/alarm2、/alarm3、/alarm4做同样的修改
2. 在/all-alarms路由聚合结果
用Promise.all并行调用所有抽离后的函数,一次性获取所有告警数据,最后聚合返回。
示例:
router.get('/all-alarms', authenticateUser, getSiteIds, async (req, res) => { try { // 并行执行所有数据查询,比串行执行效率更高 const [alarm1Data, alarm2Data, alarm3Data, alarm4Data] = await Promise.all([ getAlarm1Data(req), getAlarm2Data(req), getAlarm3Data(req), getAlarm4Data(req) ]); // 自定义聚合后的响应结构 res.json({ alarm1: alarm1Data, alarm2: alarm2Data, alarm3: alarm3Data, alarm4: alarm4Data, summary: { totalAlarms: alarm1Data.length + alarm2Data.length + alarm3Data.length + alarm4Data.length, targetSites: req.siteIds } }); } catch (err) { res.status(500).json({ error: 'Failed to fetch all alarms', details: err.message }); } });
3. 可选:单独处理单个告警的错误
如果希望某个告警查询失败时,不影响其他告警结果返回,可以给每个Promise添加catch处理:
const [alarm1Data, alarm2Data, alarm3Data, alarm4Data] = await Promise.all([ getAlarm1Data(req).catch(err => ({ status: 'failed', error: err.message })), getAlarm2Data(req).catch(err => ({ status: 'failed', error: err.message })), getAlarm3Data(req).catch(err => ({ status: 'failed', error: err.message })), getAlarm4Data(req).catch(err => ({ status: 'failed', error: err.message })) ]);
这样即使某一个告警获取失败,其他成功的结果依然会正常返回,同时失败的告警会带上对应的错误信息。
内容的提问来源于stack exchange,提问作者Ke_Sandaru
相关产品推荐
相关产品推荐

