Jahanzaib Aslam
Jahanzaib Aslam

Reputation: 2834

Async.map and async.waterfall not working together as expected

I am using Async. async.map() to bind my data array with a function and async.waterfall() in that function to run function in a series but waterfall is not working as expected. I also tried series but no success.

var myData = [1,2,3];
async.map(myData, myExport, function (err, result) {
  if(!err) {
    console.log('Finished: ' + result);
    } else {
    console.log('Error: ' + err);
}});

function myExport(item, callback) {
  console.log('item Value: ', item );
  async.waterfall([function(cb){
    console.log(' -> exportData: ', item);

  },function(response,cb){
    console.log(' -> saveData: ', item);
  },
  function(response,cb){
    console.log(' -> updateData: ', item);
  }], function(err,result){
    if(!err) {
      console.log('Perfect: ',result);
    } else {
      console.log('Error: ',err);
    }
  })
}

Output:

item Value:  1
 -> exportData:  1
item Value:  2
 -> exportData:  2
item Value:  3
 -> exportData:  3

Required Output:

item Value:  1
 -> exportData:  1
 -> saveData:    1
 -> updateData:  1
item Value:  2
 -> exportData:  2
 -> saveData:    2
 -> updateData:  2
item Value:  3
 -> exportData:  3
 -> saveData:    3
 -> updateData:  3

Upvotes: 2

Views: 1433

Answers (2)

clay
clay

Reputation: 6017

When using async, be sure to call your callbacks! In your waterfall methods, make sure to call cb(null, item) so the waterfall knows when yo continue. Inside your mapping function myExport, be sure to call callback when the waterfall has finished.

Working Code:

    var async = require('async');

    var myData = [1,2,3];
    async.mapSeries(myData, myExport, function (err, result) {
      if(!err) {
        console.log('Finished: ' + result);
        } else {
        console.log('Error: ' + err);
    }});

    function myExport(item, callback) {
      console.log('item Value: ', item );
      async.waterfall([function(cb){
        console.log(' -> exportData: ', item);
          cb(null, item);

      },function(response,cb){
        console.log(' -> saveData: ', item);

          cb(null, item);
      },
      function(response,cb){
        console.log(' -> updateData: ', item);

          cb(null, item);
      }], function(err,result){
        if(!err) {
          console.log('Perfect: ',result);
        } else {
          console.log('Error: ',err);
        }
          callback( err, result);
      })
    }

Output:

    chimmelb:~/Documents/workspace/scratch$ node index.js 
    item Value:  1
     -> exportData:  1
     -> saveData:  1
     -> updateData:  1
    Perfect:  1
    item Value:  2
     -> exportData:  2
     -> saveData:  2
     -> updateData:  2
    Perfect:  2
    item Value:  3
     -> exportData:  3
     -> saveData:  3
     -> updateData:  3
    Perfect:  3
    Finished: 1,2,3

Upvotes: 4

Rodrigo Medeiros
Rodrigo Medeiros

Reputation: 7862

You have to call the callbacks passed to your waterfall functions in order to let it know when you're done, like:

function myExport(item, callback) {
  console.log('item Value: ', item );
  async.waterfall([function(cb){
    console.log(' -> exportData: ', item);
    cb(null, item);
  }, function(response,cb){
    console.log(' -> saveData: ', response);
    cb(null, response);
  }, function(response,cb){
    console.log(' -> updateData: ', response);
    cb(null, response);
  }], function(err,result){
    if(!err) {
      console.log('Perfect: ',result);
    } else {
      console.log('Error: ',err);
    }
  })
}

Upvotes: 2

Related Questions