Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to avoid callback chains?

I need a bunch of functions to be called in strict order. It's also very important that the next function waits until the previous one has finished.

Right now I'm using chained callbacks:

callMe1(function(){
    callMe2(function(){
        callMe3(function(){

            callMeFinal();

        });
    });
});

This works but seems to be a little ugly.

Any suggestions for a different approach?

like image 518
ezmilhouse Avatar asked Mar 08 '11 09:03

ezmilhouse


People also ask

What is callback chaining?

November 22, 2020 July 14, 2021 SpectrumsTutz. A callback is a function passed as an input parameter to a function, so that the function can use it for processing it's data. Here is an example where the array. forEach() is using sayHello or sendEmail as callback for processing it data.

Are callback always asynchronous?

The function that takes another function as an argument is called a higher-order function. According to this definition, any function can become a callback function if it is passed as an argument. Callbacks are not asynchronous by nature, but can be used for asynchronous purposes.

Do promises replace callbacks?

Promises are JavaScript objects that represent an eventual completion or failure of an asynchronous operation. A promise is a returned object where you attach callbacks, instead of passing callbacks into a function. the place where you attach the callback after a successful completion of a task is called, .


3 Answers

If you use jQuery, then you can use queue to chain the functions.

$(document)
  .queue(callMe1)
  .queue(callMe2);

where callMeX should be of form:

function callMeX(next) {
    // do stuff
    next();
}
like image 180
Felix Kling Avatar answered Oct 12 '22 15:10

Felix Kling


You can implement a "stack" system:

var calls = [];

function executeNext(next) {
    if(calls.length == 0) return;
    var fnc = calls.pop();
    fnc();
    if(next) {
        executeNext(true);
    }
}

/*To call method chain synchronously*/
calls.push(callMe3);
calls.push(callMe2);
calls.push(callMe1);
executeNext(true);

/*To call method chain asynchronously*/
calls.push(callMe3);
calls.push(function(){
    callMe2();
    executeNext(false);
});
calls.push(function(){
    callMe1();
    executeNext(false);
});
like image 42
The Scrum Meister Avatar answered Oct 12 '22 15:10

The Scrum Meister


Not sure if this would help you, but there is a great article on using deferreds in jQuery 1.5. It might clean up your chain a bit...

Also, my answer on Can somebody explain jQuery queue to me has some examples of using a queue for ensuring sequential calls.

like image 23
gnarf Avatar answered Oct 12 '22 15:10

gnarf