Search code examples
node.jspromisebluebird

How to use bluebird promise for specific scenario


I need to use bluebird promise for following scenario (already implemented in native promise using sequential approach), but confuse how to do it in bluebird.

data : 
  [
     {
         field1 : value1,
         field2 : [
             subfield1 : subvalue1,
             subfield2 : subvalue2 
         ]
         field3 : value3,
     },
     {
         field1 : value1,
         field2 : [
             subfield1 : subvalue1,
             subfield2 : subvalue2 
         ]
         field3 : value3,
     }
  ]
  • So I first I need a promise based parallel loop for each block
  • In each block I need to perform four parallel separate function ( they have their own logic like http/db )
  • Then I need fifth function which need data comes from one of above four functions
  • Then I need save function
  • Then same logic repeat for next block
  • finally resolve promise

Currently I tried similar to following

var bbPromise = require("bluebird");

db.connect(dsn).then(prepareData).then( (results) => {

}).catch( (err) => {
    console.log(err)

});


function prepareData(dbObject) {

    let recordsToInsert = [];
    let promises = [];
    request.forEach(function(row, idx) {

        let procesedRow = {
            // data build from row
        };

        promises.push( childFunction(procesedRow));

    });

    bbPromise.all( promises).then( (results) => {
        // resolve here ?
    })
}

function childFunction(data) {
   bbPromise.join( 
        firstFunction(data), 
        secondFunction(data), 
        thirdFunction(data),
        fourthFunction(data)
    )
    .then( (results) => {
        data.firstResults = results[0];

        data.secondResults = results[1];

        data.thirdResults = results[2];

        data.fourthResults = results[3];

        return data;

    }).then( fifthFunction )
    .then( (results) => {
        data.fifthResults = results; 
        return insertData(data);
    })
    .then( (results) => {
        bbPromise.resolve(results);
    });
}

Its working but final successful call (See resolve here ?) executed before any of actual operations.


Solution

  • The import thing to understand is that promises are result values. You must not forget to return them, otherwise they will get ignored. You don't need to "resolve anything", all you need to do is return the promises and they will chain automatically:

    function prepareData(dbObject) {
        let recordsToInsert = [];
        let promises = request.map(function(row, idx) {
    //                         ^^^
            let procesedRow = {
                // data build from row
            };
            return childFunction(procesedRow);
    //      ^^^^^^ (ok, `push` would've worked as well)
        });
        return bbPromise.all(promises);
    //  ^^^^^^
    }
    
    function childFunction(data) {
        return bbPromise.join(
    //  ^^^^^^
            firstFunction(data), 
            secondFunction(data), 
            thirdFunction(data),
            fourthFunction(data)
        ).then(results => {
            data.firstResults = results[0];
            data.secondResults = results[1];
            data.thirdResults = results[2];
            data.fourthResults = results[3];
            return data;
        }).then(fifthFunction).then(results => {
            data.fifthResults = results; 
            return insertData(data);
        });
    }