1

I want to synchronously run a series of functions using Async.js waterfall. All is well, except for my MongoDB query that runs asynchronously despite being inside the synchronous waterfall function. Given an array of 5 objects to run, the MongoDB step will run for all 5 objects before task3 even starts! The below code illustrate my process:

// I want to send all 5 objects into the waterfall
var arrayOfObjects = [{name: 'Obj1'},{name: 'Obj2'},{name: 'Obj3'},{name: 'Obj4'},{name: 'Obj5'}]

// but for now just sending 1 object into waterfall
var myObject = {name: 'Obj1'};

async.waterfall([
        async.apply(task1, myObject)
        task2,
        task3
    ], function(err, myObject){
        console.log("Success!");
    }
);

task1 = function(myObject, callback){
   myObject.propA = "A";
   callback(null, myObject);
}

// Check MongoDB with a query
task2 = function(myObject, callback){
   Items.find({propB: "B"}, function(err, item){
      if(item){
         myObject.propB = item.propB;
         callback(null, myObject);
      }else{
         return callback("Nothing with propB found!");
      }
   })
}

// call external API and wait on the response
task3 = function(myObject, callback){
   FB.api('/563256426/feed', function(res, err){
      myObject.propC = "C";
      callback(null, myObject);
   })
}

Unfortunately task2 (involving Mongo query) runs immediately. When given an array of 5 objects to waterfall, task2 will run on all 5 objects before the rest of the code (task3) can finish running. How can I force task3 to finish running before the next waterfall?

Kangze Huang
  • 351
  • 7
  • 22
  • Try [**`async.series`**](https://github.com/caolan/async#seriestasks-callback) using an `myObject` instead of an array. Besides, the callback in `Items.find(.., callback)` returns a cursor that can be used to iterate over results, not an array of documents hence the line `myObject.propB = item.propB;` will throw an error. Or you can update `task2`'s `find()` cursor to call the `toArray(callback)` method that reads in all the records to memory. – chridam Apr 13 '16 at 13:23
  • Interesting, what is the difference between `async.series` and `async.waterfall`? I see that both run in series but `waterfall` uses a task `array` whereas `series` uses a `collection` object? – Kangze Huang Apr 13 '16 at 14:03
  • This question has been answered in [this post](https://stackoverflow.com/questions/12030248/what-is-the-right-way-to-make-a-synchronous-mongodb-query-in-node-js?rq=1) – Chege Jul 09 '17 at 21:36

0 Answers0