简体   繁体   English

Bluebird 中一系列 Promise 链的序列化执行

[英]Serialized Execution of an Array of Promise Chains in Bluebird

I am trying to build an array of Promises chains and get them to execute in order.我正在尝试构建一系列 Promises 链并让它们按顺序执行。 Each chain completes before the next entry in the array executes.每个链在数组中的下一个条目执行之前完成。 For example: [connect1, connect2, connect3] where each "task" contain a chain of some number of steps.例如: [connect1, connect2, connect3]其中每个“任务”包含一定数量的步骤链。

One of the big problems I have is being able to build the chain and add it to the array--since it has already began execution.我遇到的大问题之一是能够构建链并将其添加到数组中——因为它已经开始执行。

Some of the test code I have been toying with is here:我一直在玩的一些测试代码在这里:

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;

}

Once I have the chains for each "task" in the array, I want to execute the chain in order.一旦我拥有数组中每个“任务”的链,我想按顺序执行链。 So my goal is to get the output to be:所以我的目标是让输出为:

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}

Instead using my code I see:而是使用我的代码,我看到:

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}

I am very green when it comes to Promises and I am trying to understand ( in no specific order): 1. Why the promise execution appears to interleave (all step1's done, then step2, etc)?当谈到 Promises 时,我非常绿色,我试图理解(没有特定的顺序): 1. 为什么 Promise 执行似乎是交错的(所有 step1 都完成了,然后是 step2 等等)? 2. How can I get serialized execution line my expected output above? 2. 如何在上面的预期输出中获得序列化的执行行? 3. Can the chains be setup in a deferred manner? 3. 链可以以延迟方式设置吗? I saw my line current = current.then(taskWithState);我看到我的行current = current.then(taskWithState); ultimately calls async.invoke with Bluebird, but I didn't see a way to avoid this.最终使用 Bluebird 调用async.invoke ,但我没有找到避免这种情况的方法。

Any advice or help would be much appreciated.任何建议或帮助将不胜感激。

Your buildChain() function EXECUTES your operations.您的buildChain()函数执行您的操作。 It starts running them immediately.它立即开始运行它们。

So, this code:所以,这段代码:

var q = [ ];
q.push(buildChain(1)); // e.g. connect1
q.push(buildChain(2)); // e.g. connect2
q.push(buildChain(3)); // e.g. connect3

Starts running all three chains right away.立即开始运行所有三个链。 So, you have three promise chains running in parallel, not in sequence.因此,您有三个并行运行的承诺链,而不是按顺序运行。

FYI, this line of code should have been an interesting clue:仅供参考,这行代码应该是一个有趣的线索:

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

Because you're not actually doing anything when Promise.each() calls its callback.因为当Promise.each()调用它的回调时,你实际上并没有做任何事情。 As such, you have not given it any control over your operations.因此,您没有赋予它任何对您的操作的控制权。 They've already been started before Promise.each() even runs.它们甚至在Promise.each()运行之前就已经启动了。


You can use Promise.each() to solve this, but you need to use it as intended.您可以使用Promise.each()来解决此问题,但您需要按预期使用它。 It expects you to pass it an array of something and an iterator that operates on the items in the array.它希望你向它传递一个数组和一个对数组中的项目进行操作的迭代器。 You aren't doing anything like that.你不会做那样的事情。 You're passing it an array of promises that have already started executing.您正在向它传递一组已经开始执行的承诺。


You can fix it by changing streamConnect() to this:您可以通过将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;

}

This doesn't start executing each chain UNTIL called by Promise.each() .这不会开始执行由Promise.each()调用的每个链 UNTIL。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM