Timeout a promise after a specified amount of time
Note
You may want to use AbortSignal.timeout()
instead. Learn more.
import {setTimeout} from 'node:timers/promises'; import pTimeout from 'p-timeout'; const delayedPromise = setTimeout(200); await pTimeout(delayedPromise, { milliseconds: 50, }); //=> [TimeoutError: Promise timed out after 50 milliseconds]
Returns a decorated input
that times out after milliseconds
time. It has a .clear()
method that clears the timeout.
If you pass in a cancelable promise, specifically a promise with a .cancel()
method, that method will be called when the pTimeout
promise times out.
Type: Promise
Promise to decorate.
Type: object
Type: number
Milliseconds before timing out.
Passing Infinity
will cause it to never time out.
Type: string | Error | false
Default: 'Promise timed out after 50 milliseconds'
Specify a custom error message or error to throw when it times out:
message: 'too slow'
will throw TimeoutError('too slow')
message: new MyCustomError('it’s over 9000')
will throw the same error instancemessage: false
will make the promise resolve with undefined
instead of rejectingIf you do a custom error, it's recommended to sub-class TimeoutError
:
import {TimeoutError} from 'p-timeout'; class MyCustomError extends TimeoutError { name = "MyCustomError"; }
Type: Function
Do something other than rejecting with an error on timeout.
You could for example retry:
import {setTimeout} from 'node:timers/promises'; import pTimeout from 'p-timeout'; const delayedPromise = () => setTimeout(200); await pTimeout(delayedPromise(), { milliseconds: 50, fallback: () => { return pTimeout(delayedPromise(), {milliseconds: 300}); }, });
Type: object
with function properties setTimeout
and clearTimeout
Custom implementations for the setTimeout
and clearTimeout
functions.
Useful for testing purposes, in particular to work around sinon.useFakeTimers()
.
Example:
import {setTimeout} from 'node:timers/promises'; import pTimeout from 'p-timeout'; const originalSetTimeout = setTimeout; const originalClearTimeout = clearTimeout; sinon.useFakeTimers(); // Use `pTimeout` without being affected by `sinon.useFakeTimers()`: await pTimeout(doSomething(), { milliseconds: 2000, customTimers: { setTimeout: originalSetTimeout, clearTimeout: originalClearTimeout } });
Type: AbortSignal
You can abort the promise using AbortController
.
Requires Node.js 16 or later.
import pTimeout from 'p-timeout'; import delay from 'delay'; const delayedPromise = delay(3000); const abortController = new AbortController(); setTimeout(() => { abortController.abort(); }, 100); await pTimeout(delayedPromise, { milliseconds: 2000, signal: abortController.signal });
Exposed for instance checking and sub-classing.
Modern alternative to
p-timeout
Asynchronous functions like fetch
can accept an AbortSignal
, which can be conveniently created with AbortSignal.timeout()
.
The advantage over p-timeout
is that the promise-generating function (like fetch
) is actually notified that the user is no longer expecting an answer, so it can interrupt its work and free resources.
// Call API, timeout after 5 seconds const response = await fetch('./my-api', {signal: AbortSignal.timeout(5000)});
async function buildWall(signal) { for (const brick of bricks) { signal.throwIfAborted(); // Or: if (signal.aborted) { return; } await layBrick(); } } // Stop long work after 60 seconds await buildWall(AbortSignal.timeout(60_000))
You can also combine multiple signals, like when you have a timeout and an AbortController
triggered with a “Cancel” button click. You can use the upcoming AbortSignal.any()
helper or abort-utils
.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4