Dealing with asynchronously initialized components
Throughout this book, we have stressed how important asynchronous programming is in JavaScript and Node.js, and we have learned a great deal about different ways and patterns to use asynchronous programming effectively. At this point, you might be wondering: why are there still so many synchronous APIs in Node.js, such as readFileSync() from node:fs?
One of the reasons synchronous APIs exist in the Node.js core modules and many npm packages is that they are convenient for handling initialization tasks. In simple programs, using synchronous APIs during initialization can simplify things significantly, and the typical drawbacks of synchronous code remain contained since they only affect the program once, at startup or when a particular component is initialized.
However, relying on synchronous APIs is not always possible. In some cases, a synchronous version may not be available, especially for components that need to perform...