I'm trying to run a sequence of promises using the Q library.
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.
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.
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(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.
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:
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.
Drop the useless _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:
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;
});
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.