how do i create a non-blocking asynchronous function in node.js?

Cross-posted from Reddit.


The purpose of asynchronous functions in JavaScript is a little bit different from what you seek.

Remember that JavaScript is single-threaded — it can only do one thing at a time. Here is some traditional, blocking code:

sys.puts("Before");
sleep(10);
sys.puts("After");

In a real-world web application, the sleep() might instead be a time-consuming database call, network request (like waiting for data from the user’s web browser), helper tool, or file access.

If you used blocking calls like the above, the Node.js server would’t be able to do anything else (like starting to handle other web requests) while waiting.

PHP and many other web programming environments handle this by creating totally separate threads for each request. Node.js uses callback functions. You could write the same code like this, instead:

sys.puts("Before");
setTimeout(function(){
    sys.puts("After");
}, 10000);

Here, you create a function and pass it to setTimeout(). Its code hasn’t run yet, but when it does, it will have access to all the scope (all the variables) where it was created. setTimeout() gets a reference to the function and schedules an event to fire on the event loop after the timeout expires.

The event loop is, essentially, a Node.js program’s to-do list (they’re common — all the GUI applications running on your computer probably use event loops!).

After the call to setTimeout(), the current function keeps executing. It eventually returns, and the function which called it returns, and so on, until the program ends up back in the event loop. The event loop looks to see if anything has happened (e.g. an incoming request) while your code was executing, and calls the appropriate function in your code. If not, it waits until something does happen (like the timeout expiring).

Asynchronous code doesn’t let your code do many things at the same time, it does eliminate blocking when some code depends on something external to continue.

It’s rare that you need to do blocking work inside your Node.js program. If you do, you should separate that work out into a separate process (which can even be another Node.js program), or write a C/C++ addon which is free to use threads.

Leave a Comment