我正在尝试使用Q库运行一系列承诺。
合并注释函数在数据库中创建一个新注释,由于一些独特的约束,我必须按顺序运行这些函数。
promises顺序运行没问题,但我需要将所有newNotes推送到workNotes中的数组中,然后解析该数组。
我所尝试的一切都在链条结束之前解决了这个承诺。
为了澄清这个问题,我需要在链完成后解析notesList,并且每个生成的newNote都被推送到notesList。
workNotes(notes){
var _this = this;
var notesList = [];
return new Promise(
function(resolve,reject){
var chain = Q.when();
notes.forEach(function(note){
chain = chain.then(function(newNote){
_this.notesList.push(newNote);
return _this.mergeNotes(note);
});
});
resolve(notesList)
}
);
}
mergeNotes(notes){
return new Promise(
function(resolve,reject){
doSomething(note)
.then(function(newNote){
resolve(newNote);
})
}
);
}
答案 0 :(得分:0)
更改mergeNotes()
以返回新承诺:
mergeNotes(notes){
return doSomething(note);
}
你回复了一个承诺,但它与doSomething()
承诺没有任何联系,因此它没有等待。
避免在新创建的承诺中包装现有承诺的promise anti-pattern。相反,只需返回你已经拥有的承诺。
我将其余代码更改为:
workNotes(notes) {
let allNotes = [];
return notes.reduce(function(p, note) {
return p.then(function() {
return mergeNotes(note);
}).then(function(newNote) {
allNotes.push(newNote);
});
}, Promise.resolve()).then(function() {
return allNotes;
});
}
使用Bluebird promise库,您可以利用Promise.mapSeries()
按顺序处理数组并返回一个解析数组,这正是您所需要的:
workNotes(notes) {
return Promise.mapSeries(notes, function(note) {
return mergeNotes(note);
});
}
workNotes()
返回的承诺的已解决值将是一系列备注。
答案 1 :(得分:0)
删除无用的_this.
(注意this
与范围无关!),避免Promise
constructor antipattern,将调用顺序交换为push
和
mergeNotes
,并使用reduce
代替forEach
将数组折叠为单个值:
function workNotes(notes) {
var notesList = [];
return notes.reduce(function(chain, note) {
return chain.then(function() {
return mergeNotes(note);
}).then(function(newNote){
notesList.push(newNote);
});
}, Q.when()).then(function() {
return notesList;
});
}