Async.js: Is a variable created in a waterfall task available in another task?

225 views Asked by At

I am freshly discovering Async.js and I wondered what was the behavior of async.waterfall when a document is found by a database query, and how to use it through different tasks.

I have this piece of code :

var _arg1;
var _arg2;
async.waterfall([
    function (callback) { // First "dummy" callback
      callback(null, _arg1, _arg2);
    },
    function (arg1, arg2, callback) {
      foo1(arg1, arg2, callback); // Built-in function, for example a database query returning a document
    },
    function (arg3, callback) {
      foo2(arg3, callback); // arg3 is the document found by the query
    },
    function (callback) {
      foo3(arg3, callback); // Here I would like to use `arg3` again
    }], 
    function (err, result) {
      if (err) {
        console.log(err);
      }
    }
);

Is it possible to use arg1 in my second task, without storing the variables every time ?

I think I could do something like this, but I'm sure it is not the best way to do it :

var _arg1;
var _arg2;
var _arg3;
async.waterfall([
    function (callback) { // First "dummy" callback
      callback(null, _arg1, _arg2);
    },
    function (arg1, arg2, callback) {
      foo1(arg1, arg2, callback); // Built-in function, for example a database query returning a document
    },
    function (arg3, callback) {
      _arg3 = arg3
      foo2(arg3, callback); // arg3 is the document found by the query
    },
    function (callback) {
      foo3(_arg3, callback); // Make use gain of `_arg3` ?
    }], 
    function (err, result) {
      if (err) {
        console.log(err);
      }
    }
);

What is the best way to manipulate different variables created in tasks?

1

There are 1 answers

3
Antonio Val On BEST ANSWER

Each waterfall function has his own scope, so it's not possible to share variables. I can only think this two options:

  • Declare outside the waterfall the variables (the one you did)
  • Pass the variables to the next function using the callbacks

Second one would be something like this:

var _arg1;
var _arg2;
async.waterfall([
    function (callback) { // First "dummy" callback
      callback(null, _arg1, _arg2);
    },
    function (arg1, arg2, callback) {
      foo1(arg1, arg2, callback); // Built-in function, for example a database query returning a document
    },
    function (arg3, callback) {
      foo2(arg3, function(err) {
        if (err) {
          callback(err);
        }
        callback(null, arg3);
      });
    },
    function (arg3, callback) {
      foo3(arg3, callback); // You can use `arg3` here again
    }], 
    function (err) {
      if (err) {
        console.log(err);
      }
    }
);

I couldn't say which one is better, in my code depending on the situation I use the first or second one.

It's been pointed out in the comments, but if you are getting to create something new I also recommend you to use Promises, code created through Async.js can get quite nasty in complex situations, especially waterfall and similar ones.