Node.js Async Tutorial


I’ve been doing a lot of backend development in Node.js recently. Node.js runs on a single threaded event loop and leverages asynchronous calls for doing various things, like I/O operations. While other languages will send a database query and wait there for the result to come back, Node.js will not. When you send a database query, Node.js will continue executing the code that comes after it, then jump back when the result is available.

This is a powerful concept that enables gains in efficiency, but occasionally requires a bit more work on your end to deal with certain situations. One of those situations, which I’ve run into quite frequently, is the need to wait for a number of asynchronous operations to finish before executing additional code.

For example, maybe you have an array of items that you want to save to your database. Once they’re all saved, you want to execute a function that calculates some stats.

Your first thought might be to do something like this:

// Loop through some items
  // Call asynchronous function, often a save() to DB

// At this point, we've fired a bunch of async calls
// but they're probably not all done executing yet

// This function is meant to be executed once all the async
// calls above are done, but we don't know if/when they are,
// and therein lies the problem with this approach

As you can see in the comments above, there’s an issue here. You may (and probably will) execute doSomethingOnceAllAreDone() before everything above it is actually done.

One of the best solutions to this problem is to use the node-async package which includes a number of functions for dealing with situations like this. I’m going to show you how to resolve this issue using two different node-async features.


First, we’ll look at the async.each() function. This is the simpler solution to the problem. The function takes an array of items, then iterates over them calling a wrapper function which accepts the item as an argument. When all the calls are complete, you specify a final function to be called.

// Include the async package
// Make sure you add "async" to your package.json
async = require("async");
// 1st para in async.each() is the array of items
  // 2nd param is the function that each item is passed to
  function(item, callback){
    // Call an asynchronous function, often a save() to DB
    item.someAsyncCall(function (){
      // Async call is done, alert via callback
  // 3rd param is the function to call when everything's done
    // All tasks are done now


The solution above works well if you simply need to iterate over a collection, but what if we have a more complex situation? Rather than iterating over a collection, async.parallel() allows you to push a bunch of (potentially unrelated) asynchronous calls into an array. Once we have the array populated, we execute all the tasks inside it, then call a function when we’re done.

// Include the async package
// Make sure you add "async" to your package.json
async = require("async");

// Array to hold async tasks
var asyncTasks = [];

// Loop through some items
  // We don't actually execute the async action here
  // We add a function containing it to an array of "tasks"
    // Call an async function, often a save() to DB
      // Async call is done, alert via callback

// At this point, nothing has been executed.
// We just pushed all the async tasks into an array.

// To move beyond the iteration example, let's add
// another (different) async task for proof of concept
  // Set a timeout for 3 seconds
    // It's been 3 seconds, alert via callback
  }, 3000);

// Now we have an array of functions doing async tasks
// Execute all async tasks in the asyncTasks array
async.parallel(asyncTasks, function(){
  // All tasks are done now


Asynchronous functionality is available in lots of programming languages, not just Javascript. If you’re new to the concept, it can take a little time to wrap your head around the challenges. Luckily for Node.js developers, the node-async package provides a ton of useful features for dealing with those challenges. The examples above solve some of the simpler situations, but only scratch the surface. Check out the node-async repo for more code and examples.

I’ve uploaded full (executable) code for the examples in this post to GitHub here:

  • Neal Griffin

    Hi there – thanks for the article. Everytime I do something asynchronously in node.js, I feel like I’m going against the grain and should be trying to figure another way. Most likely it’s just me – thanks again for the article – Neal

    • Justin Klemm

      Hey Neal, you should strive to be asynchronous wherever possible! It’s more efficient and it’s what Node was meant for. Some situations can take a little extra effort (maybe that’s what makes you feel like you’re going against the grain?), but that’s just a reality of asynchronous programming in any imperative languages. Hope the article was helpful.

    • BadOPCode

      Actually I find myself more like Justin. My thoughts go to a more monolith looping world. I mean even in the world of threads those threads are processing tasks usually in some form of loop or another. I have to stand back for a second and remember that it’s more efficient in JavaScript to say
      str.replace(/(s|t|n)/g, function(me,ws) { if (ws==’s’) return ‘[space]‘; if (ws==’t’) return ‘[tab]‘; if (ws==’n’) return ‘[enter]‘ });
      As a unverified off the top of my head example.

      Node and JavaScript focus IS definitely async but it’s not through threads and loops like we have grown used to.

  • slashzero

    THANK YOU!!!!!!!!!!!

  • Santiago

    Hi there…..loved this actually, it helped me a lot before….but now I need to iterate through a set of keys, grab something from redis for each one of them, add the resulting object to an array, and wait for all the gets are done….so how the final callback can receive the resulting array so I can call the “final final” callback that sends the array to the caller ?

    • Justin Klemm

      Hi Santiago, I’m glad the article was useful. It’s hard for me to understand exactly what you need to do, but you may need to nest multiple async calls. So for example, loop through a group of async calls, then execute callback1() when they’re complete. In callback1() you loop through another group of async calls and execute callback2() when that’s done, and so on. It’s common to go multiple callbacks deeps in Node.

  • Ken Whipday

    Hi – that was a great example of asyn.each. Just what I was looking for (I’m updating mongodb from an array). A minor question – should the 3rd comment in the async.each example state ‘first parameter in async.each..’ rather than ‘first parameter in’ ?
    Thanks again for the article!

    • Justin Klemm

      Hey Ken, I’m glad the example was useful to you, and yes, you’re right. That comment should be async.each(). I’ve updated it. Thanks for catching that and letting me know!

  • Michael Höglund

    Github async docs actually makes sense now, because of this tutorial.Thanks a bunch, Justin.

  • Jim R

    Thanks for the interesting article! Any suggested pattern for the following type of problem, where I can’t predict in advance which async calls I will need to make?

    I’m following a path through a large map, not all of which is in memory, so I load it from DB “block-by-block” as needed. I don’t know where the path will go — if it wanders out of the memory-resident part of the map, I call readMapBlock( … ) to asynchronously grab the next block of the map.

    while (notReachedEndOfPath) {
    moveAlongPath( );
    if (movedPastBoundary(x,y )) {
    readMapBlock(x,y, function(mapData ) {
    moveAlongPath( );

    // [[ ... ]]

    With a synchronous DB call, execution just resumes in-line after readMapBlock( ) returns. With Node’s …
    I can’t nest callbacks, since I don’t know how many times I’ll run of the map — each requiring a callback!?!

    Do I simply need to restructure the algorithm — have my callback be recursive?

    function traverseAsFarAsPossible( ) {

    readMapBlock(x,y, traverseAsFarAsPossible( ) {

    This problem is not as contrived as it might sounds — traversing a social network or crawling the web could be similar. This seems like the solution — is this typical in Node-land? Restructuring the underlying flow to be more asynchronous and event-driven?

    P.S. Your examples are just what I need in other cases — pre-load a bunch of map blocks to display on client.

    • Justin Klemm

      Hi Jim,

      That’s an interest scenario — though probably not that uncommon. It doesn’t sound like you’ll be able to leverage an asynchronous setup here, since your database query is “blocking”…meaning your algorithm can’t continue until it’s returned its result. This really sounds like something you’ll need to step through synchronously.

      The recursion approach is what comes to mind for me first as an efficient way to solve this. The code support is bad in these comments, so I’ve attached some sudo-code as a screenshot. I hope that’s helpful to you!

  • Mayur Rokade

    async.parallel will it execute all tasks in array simultaenously? Or one by one?

    • Justin Klemm

      It will execute them simultaneously. You can see the specifics here:

      • Mayur Rokade

        Heyy, I tried async.parallel on 40,000 async tasks. I think a lot of the tasks went missing. I mean for each output I get some output on the terminal. But a lot of tasks were missing from the output. Any idea why this happens ? Or more details are needed ?

        • Justin Klemm

          40,000 is a pretty huge number of operations to be running simultaneously. You’ll almost certainly run into system resource issues. That may be why tasks are disappearing.(Imagine if each task is using 1MB of memory. That would be ~40GB of memory, which I doubt your system has.)

          You might consider using the parallelLimit() function, which allows you to cap the number of operations running at one time. You could specify the 40,000 tasks, but then make sure that only 20, 30, 50 or whatever are running simultaneously to make sure you don’t run into resource issues.

          You should experiment with that number relative to your systems resources (both memory and CPU) and your tasks operations to figure out the optimum configuration.

  • Pingback: Node.js – Powering The Real-Time Web | The Agency

  • Pingback: Node.js Async Tutorial | 4Nodejs

  • Hrushikesh Mohapatra

    var data = {};

    async.parallel([function () {

    mysqlQuery("select * from albums", function (rows) {

    data.album = rows;


    }, function () {

    mysqlQuery("select * from songs", function (rows) {

    data.songs = rows;


    }], function () {



    In the above code mysqlQuery runs asynchronously. async call back is never executed . What mistake am i doing ?

    • Bondi French

      You need to pass a callback in the first two functions and you will get a result in the 3rd one. See

    • RusAlexander

      This is what I was looking today

  • nor

    Amazing article, thanks! now i understand this.