Timers e Scheduler
Timers do Node agendam macrotarefas no event loop - callbacks de node:timers e sleeps assíncronos de node:timers/promises alimentam retentativas, debouncing e polling sem dependências extras.
Busque em todas as páginas da documentação
Timers do Node agendam macrotarefas no event loop - callbacks de node:timers e sleeps assíncronos de node:timers/promises alimentam retentativas, debouncing e polling sem dependências extras.
import { setTimeout, setInterval } from 'node:timers/promises';
await setTimeout(500, undefined, { signal: abortController.signal });
for await (const start of setInterval(1000, Date.now())) {
console.log('tick', Date.now() - start);
}Quando usar isso:
import { setTimeout as sleep } from 'node:timers/promises';
async function retry<T>(fn: () => Promise<T>, attempts = 3): Promise<T> {
let lastErr: unknown;
for (let i = 0; i < attempts; i++) {
try {
return await fn();
} catch (err) {
lastErr = err;
if (i < attempts - 1) {
await sleep(100 * 2 ** i);
}
}
}
throw lastErr;
}
const controller = new AbortController();
const cancellable = sleep(10_000, undefined, { signal: controller.signal })
.catch((err) => console.log('cancelled', err.name));
controller.abort();
await cancellable;O que isso demonstra:
sleep de timers/promisesAbortSignal cancela timer pendente com AbortErrorsetInterval (API de promessas de timer do Node) para loops assíncronos periódicosnode:timers - fila de macrotarefas na fase de timers do libuv.ref/unref em handles de Timeout - unref permite que o processo saia se apenas timers permanecerem.scheduler (orientado a navegador) tem casos de uso limitados em servidores Node.| API | Estilo |
|---|---|
setTimeout(cb, ms) | Callback |
setTimeout(ms) de promises | await sleep |
Iterador setInterval | Periódico assíncrono |
| BullMQ / cron | Agendamentos de produção |
import { setTimeout } from 'node:timers/promises';
export async function pollUntil(
check: () => boolean | Promise<boolean>,
{ intervalMs = 200, timeoutMs = 5_000, signal }: {
intervalMs?: number;
timeoutMs?: number;
signal?: AbortSignal;
} = {},
): Promise<void> {
const deadline = Date.now() + timeoutMs;
while (!(await check())) {
if (Date.now() > deadline) throw new Error('timeout');
await setTimeout(intervalMs, undefined, { signal });
}
}setInterval com callback assíncrono lento - execuções sobrepostas. Correção: encadeie setTimeout após a conclusão do await.clearTimeout no handler de desligamento.unref em heartbeat de background - bloqueia a saída do deploy. Correção: timeout.unref() quando apropriado.| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
node-cron / K8s CronJob | Agendamentos de relógio de parede | Em processo de sub-segundo |
| Jobs atrasados do BullMQ | Retentativas distribuídas | Debounce local simples |
queueMicrotask | Adiar após a pilha | Atraso baseado em tempo |
Prazos de performance.now | Medir tempo decorrido | Agendar job para futuro distante |
Promises para código async/await; callbacks servem para APIs do tipo evento.
clearTimeout(handle) ou AbortSignal com a variante de promises.
O timer não manterá o processo vivo - útil para ticks opcionais em background.
Fases diferentes do libuv - veja Microtasks vs Macrotasks.
O lag do event loop adiciona jitter - não para garantias de tempo real rígidas.
Quebre o loop com break/return; trate AbortSignal para desligamento.
Usa node-cron internamente - separado do módulo de timers brutos.
Vitest fake timers simulam APIs de timer - use para testes determinísticos.
Limite de 32 bits assinado de ~24.8 dias para alguns internos de timer - use agendamento de Data para mais tempo.
Compare o intervalo pretendido vs o real com logs de performance.now().
Cada worker executa seus próprios timers - cron duplicado a menos que haja eleição de líder.
Timers & Scheduling cobre a interação com o event loop em profundidade.
Versões da Stack: Esta página foi escrita para Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5 e NestJS 11.
Revisado por Chris St. John·Última atualização: 16 de jul. de 2026