Sequencing Function Calls In Javascript - Are Callbacks The Only Way?
Solution 1:
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/
functionfirstFunction(){
var d = $.Deferred();
// some very time consuming asynchronous code...setTimeout(function() {
console.log('1');
d.resolve();
}, 1000);
return d.promise();
}
functionthirdFunction(){
var d = $.Deferred();
// definitely dont wanna do this until secondFunction is finishedsetTimeout(function() {
console.log('3');
d.resolve();
}, 1000);
return d.promise();
}
functionsecondFunction(){
var d = $.Deferred();
setTimeout(function() {
console.log('2');
d.resolve();
}, 1000);
return d.promise();
}
functionfourthFunction(){
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/
Solution 2:
The idea is you'd do something like the following so that once the first function was done running, it'd know what to run as opposed to you having to figure it out on your own outside the function:
functionfirstFunction(callback){
// some very time consuming asynchronous code...console.log('1');
returncallback(function(){
alert("Second function finished.");
returntrue;
});
}
functionsecondFunction(callback){
// waits for firstFunction to be completedconsole.log('2');
returncallback();
}
firstFunction(secondFunction);
Solution 3:
If I'm using callbacks, my working solution now looks like this:
one(two);
function one(callb){
console.log('1');
callb(three);
}
function four(){
console.log('4');
}
function two(callb){
console.log('2');
callb(four);
}
function three(callb){
console.log('3');
callb();
}
I find that hideous. How am I supposed to keep track of this stuff if there is more than 2-3 sequences? Shudder...
Solution 4:
It's been a while and I noticed something about deferreds
in jquery documentation, specifically the when
core API function.
$.when( $.ajax("test.aspx") ).then(function(ajaxArgs){
alert(ajaxArgs[1]); /* ajaxArgs is [ "success", statusText, jqXHR ] */
});
Code sample taken from http://jqapi.com/#p=jQuery.when
Solution 5:
I have played with the Promise, Sequence, Exception, Callback to understand how it works and finally made this code.
Call functions with callback and send result as parameter to another function in sequence and have a catch errors.
functionfirstFunction(par) {
returnnewPromise(function (resolve, reject) {
console.log("start " + par);
setTimeout(function (par) {
console.log(par);
resolve(par + 1);
}, 1000, par);
});
}
functionsecondFunction(par) {
returnnewPromise(function (resolve, reject) {
console.log("start " + par);
setTimeout(function (par) {
console.log(par);
try{
throw"Let's make an error...";
}
catch(err)
{
reject(err);
}
resolve(par + 1);
}, 1000, par);
})
}
functionthirdFunction(par) {
returnnewPromise(function (resolve, reject) {
console.log("start " + par);
setTimeout(function (par) {
console.log(par);
resolve(par + 1);
}, 1000, par);
});
}
functionCatchError(error) {
console.log("Exception: " + error);
}
//Break all chain in second functionfunctionChainBrake() {
firstFunction(1)
.then(secondFunction)
.then(thirdFunction)
.catch(CatchError);
}
//Log error and continue executing chainfunctionChainContinue() {
firstFunction(1)
.catch(CatchError)
.then(secondFunction)
.catch(CatchError)
.then(thirdFunction)
.catch(CatchError);
}
Post a Comment for "Sequencing Function Calls In Javascript - Are Callbacks The Only Way?"