Forking and joining a javascript promise chain

published Dec 17, 2015 09:30   by admin ( last modified Dec 17, 2015 10:52 )

So, I have this promise chains in Bluebird that works like a pipeline: The data comes in in one end and then gets processed and pops out in the other end. Although you actually never leave a promise chain once you're in it. So it doesn't actually pop out, but inside the last step a function call is made to a function outside of the chain.

Now, new directions are given to the developer: Besides the data which is the input of the promise chain, the chain needs to split up a bit temporarily and join again. During the split up the parallel pipelines needs to process slightly different data from each other, as defined in an array. Well, how do you do that?

It's not only a question of just doing work in parallel, since each line has one parameter now that is different from other lines. Here is one way that seems to work: You inject the array into the this object with bind and then have one step that takes that array, and makes a new array with each array value combined with all the input data.

var P = require("bluebird")

var colors =['foo', 'bar'] // the different stuff

// "0" below stands for some kind of input data
P.resolve(0).bind({colors:colors}).then(forkIt).map(remainingStuff).then(loggIt).done()

function loggIt(stuff){
    console.log("logging")
    console.log(stuff)

    }

function forkIt(stuff){
    var ret = []
    for (color of this.colors){
        ret.push({'color':color, value:stuff})
    }
    return ret
    }


function remainingStuff(stuff){
    return P.resolve(stuff).then(baz)
    }

function baz(bletch) {
     return bletch
    }

It would be even nicer if you then could use bind in each line to have this have  different contents per parallel line. But in my initial tests, this is global to the all lines so that does not work. Which can be seen of you add an additional step called bat:

function remainingStuff(stuff){
    return P.resolve(stuff).then(baz).then(bat)
    }

function baz(bletch) {
    this.color = bletch.color
     return bletch
    }

function bat(bletch) {
    console.log(this.color + bletch.color)
     return bletch
    }

 

Which will make the code print among other things:

barfoo
barbar

Instead of the desired:

foofoo
barbar