0

So I recently started playing around with Node.js which showed me asynchronous code in a way I had seen it before. The problem that I face however is that node node executes almost functions call asynchronously (if I understand correctly). So I have two functions A, B who preform some database actions. Function A needs to complete before B can start. However I realized that just calling A after B clearly doesn't cut it. So I think the node thing to do would be to have a callback :). But my productions app will probably have series with A to Z so that could get messy. However I would really appreciate an example of how to implement such an callback in node.js.

var http = require('http');

function runAllFunc() {
  funcA();
  funcB();
};

var server = http.createServer(function(req,res) {
  syncFunc();
  res.writeHead(200, {'Content-Type':'text/plain'});
  res.end('dde');
}).listen(8080);
Niels
  • 1,413
  • 3
  • 18
  • 28
  • 2
    Use promises. http://blog.slaks.net/2015-01-04/async-method-patterns/ – SLaks Feb 18 '15 at 22:30
  • 2
    [Async series](http://stackoverflow.com/questions/21288014/node-js-async-series-functions-arguments), [bluebird](http://stackoverflow.com/questions/21298190/bluebird-promises-and-then), [Q](http://stackoverflow.com/questions/15350587/serial-execution-with-q-promises) ...... – adeneo Feb 18 '15 at 22:31
  • Well, apparently it's not a `syncFunction` then… There is no magic that will let this syntax work, you'll need callbacks. – Bergi Feb 18 '15 at 22:38
  • The answer lies not in what node can do for you, but in what you can do for node... which is learning how to program asynchronously. – Ryan Wheale Feb 18 '15 at 23:02

2 Answers2

4

If you are just chaining the two functions together, I would use a traditional callback. But if you are going to have a bunch that depend on various combinations of each other, I would recommend the async module. (https://github.com/caolan/async)

Here's how you could do the above example.

var async = require('async');

var funcA = function() {
  console.log("I am function 1");
};

var funcB = function() {
  console.log("I am function 2");
};

async.auto({
  funcA: function(onADone) {
    funcA();  // call your first function here
    onADone();  // callback
  },
  funcB: ['funcA', function(onBDone) {
    // second function will not execute until first one is done
    // because it is specified above
    funcB();
    onBDone();  // callback
  }],
}, function(err, res) {
  if (err) {
    console.log("something went wrong " + err);
  } else {
    console.log("done");
  }
});
jdussault
  • 407
  • 6
  • 12
3

There are a few ways of doing this.

You can use callbacks. I don't know what your functions are doing, so my examples below will all be trivial async examples using setTimeout.

function doFirstThing(callback) {
  setTimeout(function() {
    console.log('First Thing is done');
    if (callback) {
      callback();
    }
  }, 1000);
}
function doSecondThing(callback) {
  setTimeout(function() {
    console.log('Second Thing is done');
    if (callback) {
      callback();
    }
  }, 1000);
}

doFirstThing(doSecondThing);

You can also use promises, Bluebird (https://github.com/petkaantonov/bluebird) and Q (https://github.com/kriskowal/q) are two libraries that come to mind. Here's an example with Q.

var Q = require('q');
function doFirstThing() {
  var deferred = Q.defer();
  setTimeout(function() {
    console.log('First Thing is done');
    deferred.resolve();
  }, 1000);
  return deferred.promise;
}
function doSecondThing() {
  var deferred = Q.defer();
  setTimeout(function() {
    console.log('Second Thing is done');
    deferred.resolve();
  }, 1000);
  return deferred.promise;
}

doFirstThing().then(doSecondThing).done();

Another option is the async module (https://github.com/caolan/async). Here's an example:

var async = require('async');
function doFirstThing(next) {
  setTimeout(function() {
    console.log('First Thing is done');
    next();
  }, 1000);
}
function doSecondThing(next) {
  setTimeout(function() {
    console.log('Second Thing is done');
    next()
  }, 1000);
}

async.series([doFirstThing, doSecondThing]);

Of course, there are many different ways of setting up your callbacks, using your Promise library, or workflows with async. These are only a few examples.

EDIT: Edited to include links to referenced libraries.

Gabriel
  • 570
  • 4
  • 13