理解Javascript承诺-只需要解释



这是我要做的。我需要对JSON对象进行一些预处理。为了做到这一点,我需要循环遍历每个元素,如果没有新人员的id,则为该人员执行promise,然后更新列表中的该元素。

示例:

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

第一个元素没有person id,所以我将创建一个promise,在数据库中创建person,然后更新该元素并用personId替换"John Doe"。第二个元素已经有了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

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

你不能。承诺本质上是异步的。它们不是使异步任务同步执行的工具,而是平滑处理异步结果的抽象。

您可以为每个参与者启动一个任务,如果不明显,则在数据库中异步创建它,并让它们并行运行。然后,您可以很容易地获得所有结果(承诺)并等待所有结果,这样您就可以获得所有任务的所有结果的承诺——这就是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
});

相关内容

最新更新