Javascript Bluebird中承诺链数组的序列化执行

Javascript Bluebird中承诺链数组的序列化执行,javascript,promise,bluebird,Javascript,Promise,Bluebird,我正试图构建一系列承诺链,并让它们有序地执行。每个链在数组中的下一个条目执行之前完成。例如:[connect1,connect2,connect3]其中每个“任务”包含一系列步骤 我遇到的一个大问题是能够构建链并将其添加到数组中——因为它已经开始执行了 我一直在玩的一些测试代码如下: function step1() { return new Promise(resolve => { // Normally something asnyc here

我正试图构建一系列承诺链,并让它们有序地执行。每个链在数组中的下一个条目执行之前完成。例如:
[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}
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}
说到承诺,我是个新手,我试图理解(没有具体的顺序): 1.为什么承诺执行看起来是交错的(所有步骤1都完成了,然后是步骤2,等等)? 2.如何获得上面预期输出的序列化执行行? 3.链是否可以延迟设置?我看到我的行
current=current.then(taskWithState)
最终调用
async.invoke
和Bluebird,但我没有找到避免这种情况的方法

任何建议或帮助都将不胜感激。

您的
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()
更改为:

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()
调用之前,不会开始执行每个链


工作演示:

非常感谢您的详细回复。现在,这更有意义了。
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;

}