tim tim - 2 months ago 11
Javascript Question

sequencing function calls in javascript - are callbacks the only way?

I read through various threads like this one for example.

But it really escapes me how to accomplish the following:

I have 4 functions, and want them happen one after another in sequence. Notice they are in incorrect order, to get my point across. I want the result that will output "1, 2, 3, 4'

function firstFunction(){
// some very time consuming asynchronous code...
console.log('1');
}
function thirdFunction(){
// definitely dont wanna do this until secondFunction is finished
console.log('3');
}
function secondFunction(){
// waits for firstFunction to be completed
console.log('2');
}
function fourthFunction(){
// last function, not executed until the other 3 are done.
console.log('4');
}


I tried to figure out callbacks but am getting lost :(

Isn't there some simple way to do this? Like looping through an array...

Answer

It's a great chance to start using jQuery Deferred.

Apart from the callbacks-based solution the code is readable, flexible and highly maintainable

http://jsfiddle.net/zerkms/zJhph/

function firstFunction(){
  var d = $.Deferred();
  // some very time consuming asynchronous code...
  setTimeout(function() {
    console.log('1');
    d.resolve();
  }, 1000);
  return d.promise();
}
function thirdFunction(){
  var d = $.Deferred();
  // definitely dont wanna do this until secondFunction is finished
  setTimeout(function() {
    console.log('3');
    d.resolve();
  }, 1000);
  return d.promise();
}
function secondFunction(){
  var d = $.Deferred();
  setTimeout(function() {
    console.log('2');
    d.resolve();
  }, 1000);
  return d.promise();
}
function fourthFunction(){
  var d = $.Deferred();
  // last function, not executed until the other 3 are done.
  setTimeout(function() {
    console.log('4');
    d.resolve();
  }, 1000);
  return d.promise();
}

firstFunction().pipe(secondFunction).pipe(thirdFunction).pipe(fourthFunction);​

PS: as an example of asynchronous code I've used setTimeout. The main thing is that in the end of the asynchronous part you need to call d.resolve() to continue chaining methods.

Further reading: http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/

Comments