javascript: execute a bunch of asynchronous method with one callback

I need to execute a bunch of asynchronous methods (client SQLite database), and call only one final callback.

Of course, the ugly way is:

execAll : function(callBack) {
        asynch1(function() {
            asynch2(function() {
                ...
                asynchN(function() {
                    callBack();
                })
            })
        });
    }

But I know there are better ways to do it. Intuitively I would detect when all call back has been called with a counter to call the final callback.

I think this is a common design-pattern, so if someone could point me in the right direction...

Thanks in advance !

Answers:

Answer

this is easy

var callback = (function(){
    var finishedCalls = 0;
    return function(){
        if (++finishedCalls == 4){
             //execute your action here
        }
    };
})();

Just pass this callback to all your methods, and once it has been called 4 times it will execute.

If you want to use factory for this then you can do the following

function createCallback(limit, fn){
    var finishedCalls = 0;
    return function(){
        if (++finishedCalls == limit){
             fn();
        }
    };
}


var callback = createCallback(4, function(){
    alert("woot!");
});


async1(callback);
async2(callback);
async3(callback);
async4(callback);
Answer

I've written some async utilities you might find useful, allowing you to write your example as:

function(callback) {
    async.series([
        asynch1(),
        asynch2(),
        ...
        asynchN()
    ], callback);
}

Or, if you wanted to run them in parallel, as:

function(callback) {
    async.parallel([
        asynch1(),
        asynch2(),
        ...
        asynchN()
    ], callback);
}

There are loads of other useful functions like async map/reduce too:

http://caolanmcmahon.com/async.html

Hope that helps!

Answer

You should consider using Deferred pattern for asynchronous methods. You can get more information from the this StackOverflow question and answers:

What are the differences between Deferred, Promise and Future in JavaScript?

The marked answer from jnewman was good actually!

Hope this helps.

Answer

Promises can help manage this. There are two general scenarios - parallel and serial. Parallel can be accomplished using Promise.all(), serial is more complex - task B can only start when task A is done. Here's a bare-bones sample:

// returns a promise that resolves as the task is done
const wrap = (fn, delay) => new Promise(resolve => setTimeout(_ => resolve(fn()), delay));
const task = (fn, delay) => delay ? wrap(fn, delay) : Promise.resolve(fn());

// given a list of promises, execute them one by one.
const sequence = async l => l.reduce(async (a, b) => [].concat(await a, await b));

const tasks = [
    task(_ => console.log("hello world")),
    task(_ => console.log("hello future"), 1000)
];

sequence(tasks).then(_ => console.log("all done"));

You may need some ES6/7 translation to make this work in browsers or older node versions.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.