理解Javascript承诺-只需要解释

理解Javascript承诺-只需要解释,javascript,node.js,promise,q,Javascript,Node.js,Promise,Q,这就是我要做的。我需要对JSON对象进行一些预处理。为了做到这一点,我需要循环遍历每个元素,如果一个新人没有id,则为此人做出承诺,然后更新列表中的该元素 例如: participant:[{ person:{ firstName: 'john' lastName: 'Doe' }, role: 'Plumber' }, { person: '12345a9j09kf23f3' role: 'Window Washer' }

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

例如:

participant:[{
    person:{
        firstName: 'john'
        lastName: 'Doe'
    },
    role: 'Plumber'
}, {
    person: '12345a9j09kf23f3'
    role: 'Window Washer'
}]
第一个元素没有personId,因此我将创建一个promise,在数据库中创建person,然后更新该元素并用personId替换“johndoe”。第二个元素已经有一个id,不需要转到数据库来创建一个新的person

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

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
我需要一个明确的承诺。我有麻烦了

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

您可以做的是为每个参与者启动一个任务,如果在数据库中不明显,则在数据库中异步创建该任务,并让它们并行运行。然后你很容易得到所有的结果(对他们的承诺),然后等待所有的结果,这样你就可以得到对所有任务的所有结果的承诺——这就是你所做的

与使用
foreach
进行“循环”不同,您应该始终
映射到一个新的结果—如果需要,函数式编程。它看起来是这样的:

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
});

使用异步操作时,逻辑无法同步工作。您必须为异步响应编写代码。积累承诺列表,然后使用类似
Q.all()
的方法来监视所有承诺,并在它们都完成后调用回调。你不应该这样做,因为
循环
推送
都是同步操作太棒了,我不知道map可以这样使用。伟大的