Question

I have been doing web-based Javascript (vanilla JS, jQuery, Backbone, etc.) for a few years now, and recently I've been doing some work with Node.js. It took me a while to get the hang of "non-blocking" programming, but I've now gotten used to using callbacks for IO operations and whatnot.

I understand that Javascript is single-threaded by nature. I understand the concept of the Node "event queue". What I DON'T understand is what determines whether an individual javascript operation is "blocking" vs. "non-blocking". How do I know which operations I can depend on to produce an output synchronously for me to use in later code, and which ones I'll need to pass callbacks to so I can process the output after the initial operation has completed? Is there a list of Javascript functions somewhere that are asynchronous/non-blocking, and a list of ones that are synchronous/blocking? What is preventing my Javascript app from being one giant race condition?

I know that operations that take a long time, like IO operations in Node and AJAX operations on the web, require them to be asynchronous and therefore use callbacks - but who is determining what qualifies as "a long time"? Is there some sort of trigger within these operations that removes them from the normal "event queue"? If not, what makes them different from simple operations like assigning values to variables or looping through arrays, which it seems we can depend on to finish in a synchronous manner?

Perhaps I'm not even thinking of this correctly - hoping someone can set me straight. Thanks!

Was it helpful?

Solution

In general, any function that does networking or uses timers to do things over a period of time will be asynchronous.

If the function takes a callback, you can look at what the callback is used for and usually it will be obvious whether is is asynchronous or not. If the function does not offer a callback, then it has no way of communicating asynchronous results so it is probably not asynchronous.

There's no ironclad way to tell for sure. It has to either be spelled out in the doc for a function or obvious from the way the interface works.

Asynchronous operations are different under the covers than synchronous operations in that asynch operations have the notion of setting up an operation, starting the operation and then getting notified later of progress, completion or errors in the operation. Iterating an array is a synchronous operation. It has none of these issues. The code just runs synchronously. Issuing an ajax call consists of registering a callback for state notifications, then starting the ajax call, then continuing to run other javascript and then some time later, the callback is called with a state change on the ajax call (such as completion).

OTHER TIPS

From what I understand you're not asking about what you should make asynchronous but how to tell if a function is asynchronous.

You check the documentation. Seriously - that's what it's for. You don't guess what a function does based on its name or its context just like that. If you're not sure and have access to its source code you check that.

That's the only completely reliable way.

Now for guesstimating.

  • If it accepts a callback or returns a promise it's probably asynchronous (I've seen exceptions for that rule)
  • Generally everything that is I/O related in node.js and more generally in JavaScript is done asynchronously (I've seen exceptions to that rule too)

Since JavaScript is single threaded all processing blocks until one of the following occurs

1) The current execution requests an external service such as an I/O or networking request, or a webworker request

2) A function call is put on a timer to be executed at a later time

There's no list of blocking/non-blocking functions. You should check the documentation.

Your app can encounter a race condition if multiple external services have a lock on the javascript thread and try to access it at the same time. Modern browsers and the V8 engine handle this, but you may encounter this race condition if you use phonegap and write javascript apps for mobile devices. The support isn't there to handle these race conditions.

In general, assume the code blocks unless there's a callback. And even if there's a callback, that doesn't mean it won't block.

I too am new to node.js (and JavaScript in general) and I am not used to so much asynchronous code. I just wanted to point out that in the Overview of Blocking vs Non-Blocking on nodejs.org it states that:

All of the I/O methods in the Node.js standard library provide asynchronous versions, which are non-blocking, and accept callback functions. Some methods also have blocking counterparts, which have names that end with Sync.

Licensed under: CC-BY-SA with attribution
scroll top