Node.js Developer interview question · Most asked
How has asynchronous code evolved in Node.js: callbacks, Promises and async/await?
Summary
Node started with error-first callbacks ((err, data) => {}), moved to Promises (chainable, composable) and now favors async/await on top of Promises, with promise-based core APIs like fs/promises, timers/promises and stream/promises.
Longer Answer
Callbacks led to deeply nested 'callback hell' and inconsistent error handling. Promises allow Promise.all, allSettled, race and any for composition, and async/await makes async code read sequentially with try/catch. util.promisify converts callback APIs. Always handle rejections; unhandled rejections crash the process by default since Node 15.
Code Example
import { readFile } from "node:fs/promises";
async function loadConfigs(paths) {
const results = await Promise.allSettled(paths.map((p) => readFile(p, "utf8")));
return results
.filter((r) => r.status === "fulfilled")
.map((r) => JSON.parse(r.value));
}
Key Points
- Error-first callbacks (legacy)
- Promises for composition
async/awaitwith try/catch- Promise-based core modules
- Unhandled rejections crash the process
More most-asked Node.js Developer questions
- What is the difference between `process.nextTick`, Promise microtasks, `setImmediate` and `setTimeout(fn, 0)`?
- What are the differences between CommonJS and ES modules in Node.js?
- Walk through how an Express app handles a request, including errors from async handlers.
- Explain the phases of the Node.js event loop.
- What is Node.js and why is it well suited to I/O-heavy servers?
- What are streams in Node.js and what is backpressure?
- Why is CPU-bound work a problem in Node.js and how do you handle it?
- How does middleware work in Express?