You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node+Angular项目then链提前返回空数组,如何让for循环填充数据后再返回

问题原因

你遇到的现象本质是异步任务执行顺序问题:JavaScript 中的异步 IO 操作(比如你的数据库查询 Template.findByTemplateId)不会阻塞同步代码执行,for 循环只是提交了所有的异步查询任务,不会等待任务返回结果就会直接执行后续的 .then 逻辑,此时 realTemps 还没有被填充,所以返回空数组。

解决方案

使用 Promise.all 批量等待所有异步查询完成后再返回结果,修改后的代码如下:

router.get("", (req, res, next) => {
  const token = req.headers.authorization.split(" ");
  const decoded = jwt.verify(token[1], 'secretkey');
  const decodedFactoryId = decoded.factoryId;
  let templates = [];

  Template.findAllByFactoryId(decodedFactoryId)
    .then((results) => {
      for (var i = 0; i < results.length; i++) {
        // THIS IS AN AVOIDABLE LOOP, quadratic time must be prevented by correctly formatting the data (TODO)
        for (var j = 0; j < results.length; j++) {
          if (results[i][j].id) {
            templates.push(results[i][j].id)
          }
        }
      }
    })
    .then(() => {
      console.log("templates: " + templates)
      // 把所有异步查询任务包装成Promise数组
      const queryPromises = templates.map(templateId => {
        return Template.findByTemplateId(templateId).then(result => {
          console.log("here is the result: " + JSON.stringify(result[0]))
          return result;
        })
      })
      // 返回Promise.all,等待所有查询完成后才会进入下一个then
      return Promise.all(queryPromises);
    })
    .then((realTemps) => {
      // 所有查询完成,realTemps就是所有结果组成的数组,直接返回给前端
      res.send(realTemps);
    })
    .catch(err => {
      // 错误捕获,避免接口无响应
      next(err);
    })
})
补充说明
  • Promise.all 会并行执行所有传入的 Promise 任务,等到所有任务都成功返回后,才会将结果按顺序组装成数组传给下一个 .then,刚好匹配你的需求
  • 只要有一个查询失败,Promise.all 会直接触发 catch 逻辑,方便统一处理异常

内容的提问来源于stack exchange,提问作者xxcapzxx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 19:51:03