然后在 Promise.all 完成之前执行

时间:2021-04-29 18:25:38

标签: node.js mongodb promise q

我有一段代码,我希望在 orderUpdatePromises 执行之前所有 chargeCreatePromises 都完成执行:

return Q.all(chargeCreatePromises)
  .then(function() {
    return Q.all(orderUpdatePromises)
  })

代码结构如下:

function createForThisMonth(order) {
  return Q.all([
    Order.findOne({ _id: order._id }),
    Charge.findOne({ 
      "orders._id": order._id, 
      chargeMonth: moment().format("YYYY-MM")
    })
  ]).spread(function(order, charge) {
    console.log("completed: ", order.completed)

    if (!charge && !order.completed) {
      return createChargeFromOrder(order)
      // returns a promise with Charge.findOrCreate(newCharge);
    }
  })
}

function orderUpdate(order) {
  return Q(Order.findOneAndUpdate({
    { _id: order._id },
    { $set: { completed: true } }
  }))
}

function process(orders) {
  var chargeCreatePromises = [];
  var orderUpdatePromises = [];

  orders.forEach(function(order) {
    if (order.category === 'monthly') {
      chargeCreatePromises.push(createForThisMonth(order))
    }

    orderUpdatePromises.push(orderUpdate(order))
  })

  return Q.allSettled(chargeCreatePromises)
    .then(function() {
      return Q.all(orderUpdatePromises)
    })
}

并且在不同的执行中,日志是:

completed: true
completed: false
completed: false
completed: true
completed: false

所以,我认为有时 then(Q.all(orderUpdatePromises)) 会在 Q.all(chargeCreatePromises) 完成之前执行。

谁能帮助我了解这里发生的事情并实现我的目标?

Q -> https://github.com/kriskowal/q

节点 4


编辑:

我将 Q.all(chargeCreatePromises) 更改为 Q.allSettled(chargeCreatePromises),但该行为仍然存在。 我使用此更改更新了上面的代码。

1 个答案:

答案 0 :(得分:0)

<块引用>

我希望所有 chargeCreatePromises 都在 orderUpdatePromises 执行之前完成

当您在循环中同时调用 createForThisMonth(…)orderUpdate(…) 时,执行开始。 Q.all 代码只等待它们,但它们会并发运行并以任意顺序完成。

如果您希望所有 chargeCreatePromises 首先完成,请将 orderUpdate(…) 的调用放在 .then() 处理程序中:

function process(orders) {
  var chargeCreatePromises = orders.filter(function(order) {
    return order.category === 'monthly';
  }).map(createForThisMonth);

  return Q.allSettled(chargeCreatePromises).then(function() {
    var orderUpdatePromises = orders.map(orderUpdate);
    return Q.all(orderUpdatePromises);
  });
}