等待节点承诺中的循环
Wait On For Loop In Node Promise
我正在尝试 运行 使用 Q 库的一系列承诺。
合并笔记功能在数据库中创建一个新笔记,由于一些独特的限制,我必须 运行 按顺序使用这些功能。
承诺按顺序 运行 没问题,但我需要将所有 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);
})
}
);
}
将mergeNotes()
更改为return新承诺:
mergeNotes(notes){
return doSomething(note);
}
您正在 return 承诺,但它与 doSomething()
承诺没有任何联系,因此它没有等待。
避免 promise anti-pattern 将现有承诺包装在新创建的承诺中。相反,只是 return 你已经拥有的承诺。
我会将您的其余代码更改为:
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()
按顺序处理数组和 return 解析数组,这正是您需要的:
workNotes(notes) {
return Promise.mapSeries(notes, function(note) {
return mergeNotes(note);
});
}
由 workNotes()
编辑的承诺 return 的解析值将是一组注释。
放弃无用的 _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;
});
}
我正在尝试 运行 使用 Q 库的一系列承诺。
合并笔记功能在数据库中创建一个新笔记,由于一些独特的限制,我必须 运行 按顺序使用这些功能。
承诺按顺序 运行 没问题,但我需要将所有 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);
})
}
);
}
将mergeNotes()
更改为return新承诺:
mergeNotes(notes){
return doSomething(note);
}
您正在 return 承诺,但它与 doSomething()
承诺没有任何联系,因此它没有等待。
避免 promise anti-pattern 将现有承诺包装在新创建的承诺中。相反,只是 return 你已经拥有的承诺。
我会将您的其余代码更改为:
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()
按顺序处理数组和 return 解析数组,这正是您需要的:
workNotes(notes) {
return Promise.mapSeries(notes, function(note) {
return mergeNotes(note);
});
}
由 workNotes()
编辑的承诺 return 的解析值将是一组注释。
放弃无用的 _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;
});
}