Niels
Niels

Reputation: 1603

Making Node.js code run in series

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);

Upvotes: 0

Views: 1059

Answers (2)

Gabriel
Gabriel

Reputation: 600

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.

Upvotes: 3

jdussault
jdussault

Reputation: 427

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");
  }
});

Upvotes: 4

Related Questions