A delay in Node.js is usually written as setTimeout wrapped in a promise. That works, and it is still the most common node delay you will find in application code:
await new Promise((resolve) => setTimeout(resolve, 1000));This snippet waits one second, then resolves to undefined. Node.js also ships a promise-based timer of its own, so the wrapper is not needed.
node:timers/promises gives you a delay that returns a valueThe built-in API lives in node:timers/promises. It takes the delay in milliseconds and an optional value to resolve with:
import { setTimeout } from "node:timers/promises";
const res = await setTimeout(1000, "result");
console.log(res); // Prints 'result'The call waits one second and resolves to 'result'. The promise-wrapped setTimeout always resolves to undefined, so this version saves you a closure when the sleep has to hand a value back.
ref and signal optionsA third argument takes two optional settings:
interface Options {
ref?: boolean | undefined;
signal?: AbortSignal | undefined;
}ref to false so the event loop can exitBy setting ref to false, the Node.js event loop can exit if there’s nothing else to do, even if the timeout is still pending. Use it for background work that should not hold the process open.
AbortSignal to cancel the delayYou can pass an AbortSignal to cancel the timer. Abort the controller and the pending delay rejects instead of resolving, which is how you stop a wait that is no longer needed.
Node.js now offers a built-in API for delaying processes with setTimeout from node:timers/promises. It’s a cleaner alternative to the classic promise-wrapped setTimeout, with added options like ref and signal for more control over the event loop and timer cancellation.
Occasional notes on software, tools, and things I learn. No spam.
Unsubscribe anytime.