The event loop, modules and async code
Predict the order of logs, timers and promises, and load modules correctly in CommonJS and ES module projects.
Node runs your JavaScript on a single thread. Slow work such as file reads, network calls and timers happens in the background, and their callbacks are queued to run when the thread is free. Knowing that queue order answers most output questions.
The order things run
- All synchronous code in the current script or callback.
- Microtasks:
process.nextTickcallbacks, then promise callbacks such as.thenand code afterawait. - The next event loop phase: expired timers, completed input and output callbacks, then
setImmediate.
So with a setTimeout(fn, 0) and a resolved promise, the promise callback always runs first. A long synchronous loop blocks everything, including other users' requests on a server.
Async/await and errors
An async function always returns a promise. Inside it, await pauses only that function, not the whole program. Handle failures with try/catch:
async function loadUser(id) {
try {
const user = await db.find(id);
return user;
} catch (err) {
logger.error(err);
throw err;
}
}A rejected promise that nobody handles crashes current Node versions, so every promise chain needs a catch somewhere. To run independent calls together, use Promise.all; use Promise.allSettled when you need every result even if some fail.
CommonJS and ES modules
CommonJS uses require and module.exports. A common bug is writing exports = {...}, which rebinds a local variable and exports nothing. ES modules use import and export, and a file is treated as one when it ends in .mjs or package.json has "type": "module". In ES modules, relative imports need the file extension, as in import { sum } from './utils.js'.
npm basics
dependenciesare needed at runtime;devDependenciesare tools like test runners.^1.4.2allows anything below 2.0.0;~1.4.2allows anything below 1.5.0.- Commit package-lock.json and use
npm ciin builds for repeatable installs.
Habit: for any snippet, first list the synchronous lines, then the microtasks, then the timers. Write the order down before you run it.
More in Web and app