首页 > 解决方案 > 从 Sequelize 的 Promise 中打破 for 循环

问题描述

当它找到第一个结果并返回第一个响应时,我试图打破一个续集承诺内的循环,但它总是执行整个循环。如果我将值分配给承诺内的变量,则该值会在外面消失。我已经努力了好几天,如果有人能帮助我,我将不胜感激。这是我的代码:

for (let i = (parseInt(req.query.units) - 1); i >= 0; i--) {
  console.log (i);

  db.order_planned.findAll({
    where: {
      barcode: parseInt(req.query.barcode) + i,
      stepdesc: req.query.stepdesc
    },
    limit: 1,
  }).then((data) => {
    if (data[0].length > 0) {
      data[0].barcode = (parseInt(data[0].barcode) - i);
      console.log(data[0]);
      res.status(200).json(data[0]);
      break; // illegal break
    }
  }).catch((error) => {
    let err_msg = new ErrorMsg(error);
    res.status(err_msg.status).json(err_msg);
  });
} 

标签: node.jssequelize.js

解决方案


你想遍历 n 个 promise 并返回第一个解决的 promise。 Promise.any()就是这样做的。

使用您的代码的简化版本:

const promises = [];
for (let i = (parseInt(req.query.units) - 1); i >= 0; i--) {
  promises.push(
      db.order_planned.findAll({ /*..*/ }).then((data) => {          
          /*..*/
          return data[0]; // Found your data
      });
  );
}

// As soon as the first promise is returned, log it.
Promise.any(promises).then(firstResult => console.log(firstResult));

由于 Promise 的工作方式,循环将始终在返回任何 Promise 之前完整执行。


或者,您可以使用 async/await 来获得您想要的:

for (let i = (parseInt(req.query.units) - 1); i >= 0; i--) {
    const data = await db.order_planned.findAll({ /*..*/ }); // Use await here
    if (data[0].length > 0) {
      /*..*/
      break; // Can now do a break here
    }
}

但是,这将具有更差的性能,因为 Promise 不是并行执行的。


推荐阅读