如何将两次Redis hgetall查询的结果聚合为单个接口响应
实现方案
你的问题核心是Redis的hgetall是异步回调API,无法直接同步返回查询结果,将回调包装为Promise后配合Promise.all并行查询两个键即可实现需求。
第一步:封装异步查询为Promise
把单key的查询逻辑包装为返回Promise的函数,将回调结果通过Promise向外传递:
function queryDevInfoForIndex(key: string): Promise<devInfo | null> { return new Promise((resolve, reject) => { client.hgetall(key, function (err, data) { if (err) { // 错误交给外层统一处理 return reject(err); } if (data === null) { return resolve(null); } const busInfo: devInfo = JSON.parse(JSON.stringify(data)); resolve(busInfo); }); }); }
第二步:改写请求处理函数
将处理函数改为async异步函数,用Promise.all同时发起两个Redis查询,等待全部结果返回后组装响应:
async function resolveEnergyProBusDeviceInfo2(req: any, res: any) { try { const uuid = req.params.uuid; const key0 = "stream-api-uuid." + uuid + ".0.devInfo"; const key1 = "stream-api-uuid." + uuid + ".1.devInfo"; // 并行查询两个键,比串行查询性能更高 const [bus0Info, bus1Info] = await Promise.all([ queryDevInfoForIndex(key0), queryDevInfoForIndex(key1) ]); // 和原逻辑对齐,两个键都无数据时返回204 if (!bus0Info && !bus1Info) { return res.status(204).send(); } return res.status(200).json({ uuid: uuid, bus_info0: bus0Info ? { uuid: JSON.parse(String(bus0Info.uuid)), bus_index: parseInt(String(bus0Info.bus_index)), sensors: JSON.parse(String(bus0Info.sensor)) } : null, bus_info1: bus1Info ? { uuid: JSON.parse(String(bus1Info.uuid)), bus_index: parseInt(String(bus1Info.bus_index)), sensors: JSON.parse(String(bus1Info.sensor)) } : null }); } catch (err) { // 捕获异常避免服务崩溃,按需返回错误响应 console.error('Redis查询错误', err); return res.status(500).json({ error: '内部服务错误' }); } }
关键说明
Promise.all会等待所有异步任务完成后统一返回结果,两个Redis查询并行执行,不会额外增加请求耗时- 所有错误统一在try/catch中捕获,不需要在每个查询回调里单独throw err,避免未捕获异常导致服务退出
- 保留了原逻辑中数据不存在返回204的处理,单key不存在时对应字段返回null,也可以根据业务需求调整为空对象等其他值
内容的提问来源于stack exchange,提问作者m4ng0o
相关产品推荐
相关产品推荐

