Node.js中如何在For循环及所有异步操作完成后再返回接口响应
问题根因
- 代码中调用的
ExternalServer.GetAssetsOfUser、ExternalServer.GetPriceOfAsset均为异步Promise操作,原始写法未等待异步请求返回就直接执行了res.send(body),此时所有外部接口还未响应,自然返回空数组 - 额外存在变量作用域错误:
assetsArr定义在GetAssetsOfUser的回调函数内部,回调外的赋值语句userObj.assets = assetsArr根本无法访问到该变量,即便异步请求完成也不能正确赋值
修复方案
推荐使用async/await语法改写异步逻辑,配合Promise.all批量等待所有异步操作完成后再返回响应,修复后的代码如下:
app.get("/usersData", async (req, res) => { try { // 等待数据库查询用户列表完成 const users = await Users.find({}); // 批量等待所有用户的资产查询逻辑处理完成 const body = await Promise.all(users.map(async (user) => { const userObj = { userName: user.userName, assets: [] }; // 等待当前用户的资产查询接口返回 const assets = await ExternalServer.GetAssetsOfUser(user.secretKey); // 过滤出余额大于50的资产 const validAssets = Object.values(assets).filter(asset => asset.amount > 50); // 批量等待所有有效资产的价格查询完成 const assetsArr = await Promise.all(validAssets.map(async (asset) => { const price = await ExternalServer.GetPriceOfAsset(asset.name); return { name: asset.name, value: +parseFloat(asset.amount).toFixed(4) * price }; })); userObj.assets = assetsArr; return userObj; })); // 所有逻辑处理完成后再返回结果 res.send(body); } catch (err) { // 统一捕获所有异步操作的异常,避免接口挂起 res.status(500).send({ error: "数据查询失败" }); } })
逻辑说明
- 所有异步操作前加
await关键字,代码会等待该步骤执行完成后再往下走 Promise.all会并行处理多个同批次的异步请求,相比串行等待大幅提升查询效率- 外层增加
try/catch统一捕获全链路异常,避免接口无响应或崩溃
内容的提问来源于stack exchange,提问作者Ahmad Eltobshy
相关产品推荐
相关产品推荐

