[英]Wait On For Loop In Node Promise
I'm trying to run a sequence of promises using the Q library. 我正在尝试使用Q库运行一系列的Promise。
The merge notes function creates a new note in the database and I have to run the functions in order due to some unique constraints. 合并注释功能会在数据库中创建一个新注释,由于某些独特的限制,我必须按顺序运行这些功能。
The promises are running in sequence no problem, but I need to push all of the newNotes into an array in workNotes and then resolve that array. Promise按顺序运行没有问题,但是我需要将所有newNotes推送到workNotes中的数组中,然后解析该数组。
Everything I have tried resolves the promise before the chain is over. 我尝试过的一切都可以在链条结束之前解决诺言。
To clarify the problem, I need to resolve notesList after the chain has completed and every resulting newNote has been pushed to notesList. 为了澄清这个问题,我需要在链完成并将每个结果newNote推送到notesList之后解决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);
})
}
);
}
Change mergeNotes()
to return the new promise: 更改mergeNotes()
以返回新的mergeNotes()
:
mergeNotes(notes){
return doSomething(note);
}
You were returning a promise, but it was not connected in any way to the doSomething()
promise and thus it didn't wait for that. 您正在返回一个诺言,但是它与doSomething()
诺言没有任何联系,因此它没有等待。
Avoid the promise anti-pattern of wrapping an existing promise in a newly created promise. 避免使用将现有承诺包装在新创建的承诺中的承诺反模式 。 Instead, just return the promise you already have. 相反,只需返回您已经拥有的承诺即可。
I'd change the rest of your code to this: 我将其余代码更改为此:
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;
});
}
With the Bluebird promise library, you could take advantage of Promise.mapSeries()
which processes an array in sequence and returns a resolved array which is exactly what you need: 借助Bluebird Promise.mapSeries()
库,您可以利用Promise.mapSeries()
来按顺序处理数组并返回恰好需要的已解析数组:
workNotes(notes) {
return Promise.mapSeries(notes, function(note) {
return mergeNotes(note);
});
}
The resolved value of the promise returned by workNotes()
will be an array of notes. workNotes()
返回的workNotes()
的解析值将是一个注释数组。
Drop the useless _this.
删除无用的_this.
(notice that this
is not about scope!), avoid the Promise
constructor antipattern , swap the order of calls to push
and mergeNotes
, and use reduce
instead of forEach
to fold an array to a single value: (请注意, this
与范围无关!),避免使用Promise
构造函数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;
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.