gpt4 book ai didi

javascript - Bluebird 中 Promise 链数组的序列化执行

转载 作者:行者123 更新时间:2023-11-29 21:28:21 25 4
gpt4 key购买 nike

我正在尝试构建一系列 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

立即开始运行所有三个链。因此,您有三个并行运行的 promise 链,而不是按顺序运行。

仅供引用,这行代码应该是一个有趣的线索:

var p = Promise.each(q, function(f) {return ( f )});

因为当 Promise.each() 调用它的回调时,您实际上并没有做任何事情。因此,您没有赋予它对您的操作的任何控制权。它们甚至在 Promise.each() 运行之前就已启动。


您可以使用 Promise.each() 来解决这个问题,但您需要按预期使用它。它希望您向它传递一个数组和一个对数组中的项目进行操作的迭代器。你没有做那样的事情。您向它传递了一系列已经开始执行的 promise 。


您可以通过将 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() 调用。

工作演示:https://jsfiddle.net/jfriend00/3ce0ceuy/

关于javascript - Bluebird 中 Promise 链数组的序列化执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36945655/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com