【问题标题】:Understanding Javascript Promises - Just want explanation理解 Javascript Promises - 只需要解释
【发布时间】:2014-10-23 11:47:07
【问题描述】:

这就是我想要做的。我需要对 JSON 对象进行一些预处理。为此,我需要遍历每个元素,如果没有新人的 id 则为新人做一个承诺,然后更新列表中的那个元素。

例子:

participant:[{
    person:{
        firstName: 'john'
        lastName: 'Doe'
    },
    role: 'Plumber'
}, {
    person: '12345a9j09kf23f3'
    role: 'Window Washer'
}]

第一个元素没有人员 ID,因此我将创建一个承诺,在数据库中创建人员,然后更新该元素并将“John Doe”替换为人员 ID。第二个元素已经有了id,不需要去数据库创建新人了。

此代码按原样工作。问题是我正在尝试做一个 for 循环,我需要一个同步的承诺。我有麻烦了。如何使用循环并调用 promise 或有条件地不处理 promise 并且逻辑同步工作?

Box.create(box)
.then(function(data) {
  _.forEach(participants, function (participant) {
      //This promise will be executed asynchronously, possible to make it synchronous with the for loop?
      if (typeof participant.person != 'undefined' && typeof participant.person.firstName != 'undefined') {
         Person.create(participant.person).then(function (data) {
            return Participant.create({}).then(function(data){
              newParticipants.push(data);
            })
          });
      } else {
        participants.push(participant);
      }
  });
  return Q(undefined);
}).then(function(){
 // more logic

【问题讨论】:

  • 使用异步操作时,逻辑不能同步工作。您必须为异步响应编写代码。累积一个 Promise 列表,然后使用 Q.all() 之类的东西来监视所有 Promise 并在它们全部完成后调用您的回调。
  • 你不应该这样做,因为looppush是同步操作

标签: javascript node.js promise q


【解决方案1】:

我需要一个同步的承诺。我有麻烦了

你不能。 Promises are inherently asynchronous。它们不是使异步任务同步执行的工具,它们是一种抽象,可以顺畅地处理异步结果。

您可以做的是为每个参与者触发一个任务,如果那里不明显,则在数据库中异步创建它,并让它们并行运行。然后,您轻松获取所有结果(对它们的承诺)并等待所有结果,以便您获得所有任务的所有结果的承诺 - 这就是 Q.all 所做的。

不要使用foreach“循环”,而是应该始终map 获得一个新结果——如果你愿意,可以进行函数式编程。它看起来像这样:

Box.create(box).then(function(data) {
  var participants = data.participants; // or so?
  var promises = _.map(participants, function (participant) {
    if (typeof participant.person != 'undefined' && typeof participant.person.firstName != 'undefined') {
      return Person.create(participant.person)
             .then(Participant.create)
      // a promise for the new participant, created from the data that Person.create yielded
    } else {
      return Q(participant);
      // a (fulfilled) promise for the participant that we already have
    }
  });
  return Q.all(promises);
}).then(function(participants) {
  // more logic, now with all (old+new) participants
});

【讨论】:

  • 太棒了,我不知道地图可以这样使用。太好了!
猜你喜欢
  • 2015-07-10
  • 2011-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多