Asynchronous vs Synchronous Programming in JavaScript
By: Arnold Abraham
Tags: Technology, JavaScript, Programming, Web Development, Coding

Asynchronous vs Synchronous Programming in JavaScript

JavaScript break Promises & keep Callbacks

Introduction

JavaScript gets executed by a single thread. According to this, it is advisable to avoid long-lasting operations in the first place. What we are going to do if callbacks are omnipresent?

Whenever it comes to I/O-operations, like a network or a file system, then this circumstance can get quite heavy. Fortunately, there are two kinds of callbacks in JavaScript. Want to take a really deep dive into this? Havoc’s Blog [1] did a pretty detailed investigation about that. The base difference between synchronous and asynchronous callbacks is: Synchronous callbacks are getting executed in the calling's context method, whereas asynchronous not.

A good example is to flatten an array of arrays. When this function gets executed, the passed-in parameter will be reduced to get rid of the multiple arrays inside an array and convert it into a single flattened one.

When this would be asynchronous, the function could not return to the assignment of the variable flat. It has to be synchronous to do so and is a good example for the field of application of a synchronous callback and why they are used at all.

Synchronous and asynchronous Callbacks

When there are reasons to use a synchronous callback, then there are also reasons for an asynchronous callback. Whenever the program needs external resources and has to wait for them, for example, connections being established, files are going to be downloaded, etc.

The following example will request a status code and a status message from the famous search engine Google and print it to the console. The first message that is going to be printed out is the last line of this short script: Requesting… followed by 200 and OK. This example mirrors the non-blocking and asynchronous call to I/O-Resources, propagated by JavaScript.

Crucial to the consistency and dependability of an API is its behavior. It has to be consistent and never changing like functional programming is designed. Throwing in A as an input will always return a B as an output, nothing else. Converting this back to API: A function should always return a synchronous callback XOR (exclusive or) an asynchronous one. There should be no distinction between cases where the function itself returns sometimes a synchronous and other times an asynchronous callback. When you read Havoc’s Blog-Post about that one, you will find the line “Choose sync or async, but not both” and give a well-founded justification for that:

Because sync and async callbacks have different rules, they create different bugs. It’s very typical that the test suite only triggers the callback asynchronously, but then some less-common case in production runs it synchronously and breaks (Or vice versa). Requiring application developers to plan for and test both sync and async cases is just too hard, and it’s simple to solve in the library: If the callback must be deferred in any situation, always defer it. — Havoc’s Blog

Process.nextTick versus setImmediate

JavaScript offers two functions for server-side applications: process.nextTick and setImmediate. They seem to be interchangeable at first glance. You can read them both within their documentations: nextTick [2] & setImmediate [3].

For the code interpretation on the client-side, only setImmediate is available. Both expect a callback as a parameter and will execute this callback later. Based on the definition, it seems both are doing the same. Look at the following code.

Both show to do the same. But when you look under the hood, they are both clearly different. process.nextTick will delay the execution until a later date, but before Node.JS makes I/O accesses and gives the control back to the event loop.

Imagine you are calling process.nextTick recursively. Where will this end? It ends in another delay until they have accumulated and lets the event loop starving. Giving the child a name “event loop starvation” [6].

Node.js under the Hood by dev.to, Lucas Santos (All rights reserved)

SetImmediate, the name reveals it, does execute the callback function immediately. Excuse me, not immediately, but at the next round of the event loop. Almost immediately.

If you are a true sherlock, then you solved the riddle here and found out that, especially when calling the process.nextTick with recursion and used setImmediate in the code as well, not only the event loop is left to starve but setImmediate is also being held on. This example illustrates, how important it is to know exactly what is going on with the API you use.

Use the official documentation [2], [3] to inform yourself about the difference between these two in detail, when you plan to work with them.

The last bastion: Asynchronicity

In most cases, the conversion to an asynchronous function from a synchronous one is possible by taking the process.nextTick method. The following example states a mixed-method, working asynchronous and synchronous.

Changing the synchronous part to an asynchronous one will bring uniformity and consistency to this function, stating the principle of getting B as an output when putting in A into the function every time.

Would you like to get much more detailed information? View the blog post from Isaac Z. Schlueter [5].

Conclusion

We should build programming upon stability and consistency. Just because there are variables in the code, you don’t have to make the code itself a variable. A function call has to be reliable and not case dependant. Make your callbacks either pure synchronously or pure asynchronously to avoid inconsistency and built your API upon reliability. In case of doubt, convert your synchronous call into a synthetic asynchronous one.

Good for us, that Node.JS knows both of them: process.NextTick and setImmediate.