diff --git a/source/core/timed-out.ts b/source/core/timed-out.ts index 57dc13687..53a5b6ffa 100644 --- a/source/core/timed-out.ts +++ b/source/core/timed-out.ts @@ -51,7 +51,7 @@ export default function timedOut(request: ClientRequest, delays: Delays, options request[reentry] = true; const cancelers: Array = []; const {once, unhandleAll} = unhandler(); - const handled: Record = {}; + const handled: Map = new Map(); const addTimeout = (delay: number, callback: (delay: number, event: string) => void, event: string): (typeof noop) => { const timeout = setTimeout(callback, delay, delay, event) as unknown as NodeJS.Timeout; @@ -59,7 +59,7 @@ export default function timedOut(request: ClientRequest, delays: Delays, options timeout.unref?.(); const cancel = (): void => { - handled[event] = true; + handled.set(event, true); clearTimeout(timeout); }; @@ -71,11 +71,13 @@ export default function timedOut(request: ClientRequest, delays: Delays, options const {host, hostname} = options; const timeoutHandler = (delay: number, event: string): void => { - setTimeout(() => { - if (!handled[event]) { + // Use queueMicroTask to allow for any cancelled events to be handled first, + // to prevent firing any TimeoutError unneeded when the event loop is busy or blocked + queueMicrotask(() => { + if (!handled.has(event)) { request.destroy(new TimeoutError(delay, event)); } - }, 0); + }); }; const cancelTimeouts = (): void => {