Search code examples
node.jsasynchronousbluebird

Bluebird async series call


I have this below code, but as soon as widgetsAddCall is added into array, it gets executed, and promise.each is of no use.

Function widgetsAddCall is making async request to API server and returns bluebird promisified request. I want that API call is made one after another, so that each call sends chunk of data one after another.

var chunkCnt = Math.ceil(widgetsIds.length/4000);
var responseT = Array();
var Promise = require('bluebird');

for(var cntTemp =0 ; cntTemp<chunkCnt;cntTemp++){
    var tempWidgs = widgetsIds.slice(cntTemp,cntTemp+4000);
    var query = {
        id: tempWidgs.join(',')
    };
    responseT.push(widgetsAddCall(tempWidgs,query,campRemoteId,campaign));
}

    return Promise.each(responseT,function(responses) {
      // Use the responses here
      return getWidgets(campRemoteId,campaign).then((ids) => {
            var toRemove = [];
            for(var id of ids){
                if(widgetsIds.indexOf(id)===-1){
                    toRemove.push(id);
                }
            }
            if(toRemove.length) {
                return removeWidgets(campaign, campRemoteId, toRemove);
            }
        });
    })

Solution

  • I want that API call is made one after another, so that each call sends chunk of data one after another.

    The simplest way I can think of to serialize all your calls is to prebuild your chunks into an array and then use Bluebird's Promise.mapSeries() to serially iterate through the array:

    var Promise = require('bluebird');
    
    // pre-build chunks into an array
    var chunks = [];
    var chunkCnt = Math.ceil(widgetsIds.length / 4000);
    for (var chunkIndex = 0; chunkIndex < chunkCnt; chunkIndex++) {
        chunks.push(widgetsIds.slice(cntIndex,cntIndex + 4000));
    }
    
    // now serially iterate the array
    Promise.mapSeries(chunks, function(item) {
        return widgetsAddCall(item, {id: item.join(',')}, campRemoteId, campaign);
    }).then(function(results) {
        // now process the results of widgetsAddCall() here
    });
    

    FYI, your original use of Promise.each() was not making any sense to me because you were iterating an array of promises, but then not using any info from the iteration. There seemed to be no point to the iteration. Plus, you weren't properly serializing your calls to widgetsAddCall() anyway since you were launching all those calls in parallel.