[ITEM 5] QUESTION: How to run async operations in parallel?
To efficiently execute asynchronous operations in parallel in modern JavaScript, the most reliable and elegant solution is to use the built-in construct await Promise.all([fn1(), fn2()]). The main mistake novice developers make is that they sequentially call each asynchronous function via separate await operators, which leads to unnecessary execution thread blocking and an increase in total waiting time. When you pass an array of promises to Promise.all, all asynchronous tasks start simultaneously, and code execution pauses precisely until the longest one completes.
The execution results of all passed functions are returned as a single ordered array, making them easy to access. For convenience, destructuring syntax is often used, for example, const [a, b] = await Promise.all([fetchDataA(), fetchDataB()]), which makes the code clean and readable. However, it is important to remember a key feature: if even one of the promises in the array fails (is rejected), the entire Promise.all will immediately fail, and the rest of the results will be ignored.
If your business logic critically requires obtaining the results of absolutely all requests, regardless of whether they succeeded or failed, instead of Promise.all you should use the Promise.allSettled method. It returns an array of objects describing the status of each promise (fulfilled or rejected) along with its value or error reason. This provides maximum flexibility when handling batch network requests, reading files, or performing other independent asynchronous operations in a web application.