1/9
To summarize, this is what you will learn in this chapter: • The Callback pattern, how it works, what conventions are used in Node.js, and how to deal with its most common pitfalls • The Observer pattern and how to implement it in Node.js using the EventEmitter class
Name | Mastery | Learn | Test | Matching | Spaced |
---|
No study sessions yet.
The continuation-passing style (CPS)
In JavaScript, a callback is a function that is passed as an argument to another function and is invoked with the result when the operation completes. In functional programming, this way of propagating the result is called continuation-passing style (CPS).
It is a general concept, and it is not always associated with asynchronous operations. In fact, it simply indicates that a result is propagated by passing it to another function (the callback), instead of directly returning it to the caller.
Asynchronous CPS
Non-CPS callbacks
There are several circumstances in which the presence of a callback argument might make us think that a function is asynchronous or is using a CPS. That's not always true.
Unpredictable function (Synchronous & Asynchronous)
One of the most dangerous situations is to have an API that behaves synchronously under certain conditions and asynchronously under others.
Unleashing Zalgo
"Unleashing Zalgo" refers to a problem caused by functions that have unpredictable timing. Specifically, a function might sometimes execute synchronously (immediately) and other times asynchronously (after a delay), often depending on hidden conditions like whether data is cached.
Using synchronous APIs
The lesson to learn from the unleashing Zalgo example is that it is imperative for an API to clearly define its nature: either synchronous or asynchronous.
Using synchronous I/O in Node.js is strongly discouraged in many circumstances, but in some situations, this might be the easiest and most efficient solution. Always evaluate your specific use case in order to choose the right alternative. As an example, it makes perfect sense to use a synchronous blocking API to load a configuration file while bootstrapping an application.
That’s why deferring a synchronous function to an asynchronous one is alwasy the best option, We can do it in Nodejs by leveraging process.nextTick().
Guaranteeing asynchronicity with deferred execution
Another alternative for fixing our inconsistentRead() function is to make it purely asynchronous.
The trick here is to schedule the synchronous callback invocation to be executed "in the future" instead of it being run immediately in the same event loop cycle. In Node.js, this is possible with process.nextTick(), which defers the execution of a function after the currently running operation completes.
Its functionality is very simple: it takes a callback as an argument and pushes it to the top of the event queue, in front of any pending I/O event, and returns immediately. The callback will then be invoked as soon as the currently running operation yields control back to the event loop.
NodeJS callback conventions
In Node.js, CPS APIs and callbacks follow a set of specific conventions.
These conventions apply to the Node.js core API, but they are also followed by the vast majority of the userland modules and applications. So, it's very important that you understand them and make sure that you comply whenever you need to design an asynchronous API that makes use of callbacks.