[英]Serialized Execution of an Array of Promise Chains in Bluebird
我正在尝试构建一系列 Promises 链并让它们按顺序执行。 每个链在数组中的下一个条目执行之前完成。 例如: [connect1, connect2, connect3]
其中每个“任务”包含一定数量的步骤链。
我遇到的大问题之一是能够构建链并将其添加到数组中——因为它已经开始执行。
我一直在玩的一些测试代码在这里:
function step1() {
return new Promise(resolve => {
// Normally something asnyc here
console.log("step1:", this);
resolve();
});
}
function step2() {
return new Promise(resolve => {
// Normally something asnyc here
console.log("step2:", this);
resolve();
});
}
function step3() {
return new Promise(resolve => {
// Normally something asnyc here
console.log("step3:", this);
resolve();
});
}
function promiseSeq( tasks, state ) {
let current = Promise.resolve();
for (let k = 0; k < tasks.length; ++k) {
var taskWithState = tasks[k];
if (typeof state !== 'undefined') {
taskWithState = taskWithState.bind(state);
}
current = current.then(taskWithState);
}
return current;
}
function buildChain(idx) {
// Build the connection chain (with state)
//------------------------------
var s = { conn: idx }; // some state
var q = [ step1, step2, step3 ];
return promiseSeq(q, s);
}
function streamConnect() {
// Build array of chains
//------------------------------
var q = [ ];
q.push(buildChain(1)); // e.g. connect1
q.push(buildChain(2)); // e.g. connect2
q.push(buildChain(3)); // e.g. connect3
var p = Promise.each(q, function(f) {return ( f )});
// Process promises...
p.then(function() {console.log("done")})
.catch(function(err) {console.error("catch:",err)})
return;
}
一旦我拥有数组中每个“任务”的链,我想按顺序执行链。 所以我的目标是让输出为:
step1: Object {conn: 1}
step2: Object {conn: 1}
step3: Object {conn: 1}
step1: Object {conn: 2}
step2: Object {conn: 2}
step3: Object {conn: 2}
step1: Object {conn: 3}
step2: Object {conn: 3}
step3: Object {conn: 3}
而是使用我的代码,我看到:
step1: Object {conn: 1}
step1: Object {conn: 2}
step1: Object {conn: 3}
step2: Object {conn: 1}
step2: Object {conn: 2}
step2: Object {conn: 3}
step3: Object {conn: 1}
step3: Object {conn: 2}
step3: Object {conn: 3}
当谈到 Promises 时,我非常绿色,我试图理解(没有特定的顺序): 1. 为什么 Promise 执行似乎是交错的(所有 step1 都完成了,然后是 step2 等等)? 2. 如何在上面的预期输出中获得序列化的执行行? 3. 链可以以延迟方式设置吗? 我看到我的行current = current.then(taskWithState);
最终使用 Bluebird 调用async.invoke
,但我没有找到避免这种情况的方法。
任何建议或帮助将不胜感激。
您的buildChain()
函数执行您的操作。 它立即开始运行它们。
所以,这段代码:
var q = [ ];
q.push(buildChain(1)); // e.g. connect1
q.push(buildChain(2)); // e.g. connect2
q.push(buildChain(3)); // e.g. connect3
立即开始运行所有三个链。 因此,您有三个并行运行的承诺链,而不是按顺序运行。
仅供参考,这行代码应该是一个有趣的线索:
var p = Promise.each(q, function(f) {return ( f )});
因为当Promise.each()
调用它的回调时,你实际上并没有做任何事情。 因此,您没有赋予它任何对您的操作的控制权。 它们甚至在Promise.each()
运行之前就已经启动了。
您可以使用Promise.each()
来解决此问题,但您需要按预期使用它。 它希望你向它传递一个数组和一个对数组中的项目进行操作的迭代器。 你不会做那样的事情。 您正在向它传递一组已经开始执行的承诺。
您可以通过将streamConnect()
更改为streamConnect()
来修复它:
function streamConnect() {
var q = [1,2,3];
var p = Promise.each(q, function(item) {
return buildChain(item);
});
// Process promises...
p.then(function() {console.log("done")})
.catch(function(err) {console.error("catch:",err)})
return;
}
这不会开始执行由Promise.each()
调用的每个链 UNTIL。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.