Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript - waiting for a number of asynchronous callbacks to return?

What's the best way/library for handling multiple asynchronous callbacks? Right now, I have something like this:

_.each(stuff, function(thing){
   async(thing, callback);
});

I need to execute some code after the callback has been fired for each element in stuff.

What's the cleanest way to do this? I'm open to using libraries.

like image 226
Stefan Kendall Avatar asked Apr 24 '12 02:04

Stefan Kendall


People also ask

How do I make async call wait?

Inside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.

How do you wait for async to finish JavaScript?

The await operator is used to wait for a Promise. It can be used inside an Async block only. The keyword Await makes JavaScript wait until the promise returns a result. It has to be noted that it only makes the async function block wait and not the whole program execution.

What is asynchronous callback in JavaScript?

Asynchronous callbacks are functions passed to another function that starts executing code in the background. Typically, when the code in the background finishes, the async callback function is called as a way of notifying and passing on data to the callback function that the background task is finished.

What is asynchronous await in JavaScript?

The await keyword is used inside the async function to wait for the asynchronous operation. The syntax to use await is: let result = await promise; The use of await pauses the async function until the promise returns a result (resolve or reject) value.


4 Answers

Since you're already using Underscore you might look at _.after. It does exactly what you're asking for. From the docs:

after    _.after(count, function)

Creates a version of the function that will only be run after first being called count times. Useful for grouping asynchronous responses, where you want to be sure that all the async calls have finished, before proceeding.

like image 87
Jordan Running Avatar answered Oct 23 '22 14:10

Jordan Running


There is a great library called Async.js that helps solve problems like this with many async & flow control helpers. It provides several forEach functions that can help you run callbacks for every item in a an array/object.

Check out: https://github.com/caolan/async#forEach

// will print 1,2,3,4,5,6,7,all done

var arr = [1,2,3,4,5,6,7];

function doSomething(item, done) {
  setTimeout(function() {
    console.log(item);
    done(); // call this when you're done with whatever you're doing
  }, 50);
}

async.forEach(arr, doSomething, function(err) {
    console.log("all done");
});
like image 33
Jamund Ferguson Avatar answered Oct 23 '22 13:10

Jamund Ferguson


I recommend https://github.com/caolan/async for this. You can use async.parallel to do this.

function stuffDoer(thing) {
    return function (callback) {
        //Do stuff here with thing
        callback(null, thing);
    }
}

var work = _.map(stuff, stuffDoer)
async.parallel(work, function (error, results) {
    //error will be defined if anything passed an error to the callback
    //results will be an unordered array of whatever return value if any
    //the worker functions passed to the callback
}
like image 2
Peter Lyons Avatar answered Oct 23 '22 15:10

Peter Lyons


async.parallel() / async.series should suit your requirement. You can provide with a final callback that gets executed when all the REST calls succeed.

async.parallel([
    function(){ ... },
    function(){ ... }
], callback);
async.series([
    function(){ ... },
    function(){ ... }
], callback);
like image 1
skashyap Avatar answered Oct 23 '22 15:10

skashyap