这是我尝试做的事情。我需要对JSON对象进行一些预处理。为了做到这一点,我需要循环遍历每个元素,如果没有该人的id,则为新人做一个承诺,然后在列表中更新该元素。
示例:
participant:[{
person:{
firstName: 'john'
lastName: 'Doe'
},
role: 'Plumber'
}, {
person: '12345a9j09kf23f3'
role: 'Window Washer'
}]
第一个元素没有人名,所以我要创建一个承诺,在数据库中创建人,然后更新该元素并替换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
答案 0 :(得分: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
});