The Callback Pattern: Synchronous vs. Asynchronous (II)
Learn about synchronous APIs and asynchronicity with deferred execution.
We'll cover the following...
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.
One possible fix for our inconsistentRead()
function is to make it completely synchronous. This is possible because Node.js provides a set of synchronous direct style APIs for most basic I/O operations. For example, we can use the fs.readFileSync()
function in place of its asynchronous counterpart. The code would become as follows:
import { readFileSync } from 'fs'const cache = new Map()function consistentReadSync (filename) {if (cache.has(filename)) {return cache.get(filename)} else {const data = readFileSync(filename, 'utf8')cache.set(filename, data)return data} }console.log(consistentReadSync("data.txt"))// the next call will read from the cacheconsole.log(consistentReadSync("data.txt"))
We can see that the entire function was also converted into a direct style. There’s no reason for a function to have a CPS if it’s synchronous. In fact, it’s always best practice to implement a synchronous API using a direct style. This will eliminate any confusion around its nature and will also be more efficient from a performance perspective.
Pattern
Always choose a direct style for purely synchronous functions.
Remember that changing an API from CPS to a direct style, or from asynchronous to synchronous or vice versa, might also require a ...