Timeout a promise after a specified amount of time
npx @tessl/cli install tessl/npm-p-timeout@6.1.00
# p-timeout
1
2
p-timeout provides a utility for adding timeout functionality to JavaScript promises, allowing developers to set time limits on asynchronous operations. It offers a simple API that wraps any promise and automatically rejects it with a TimeoutError if it doesn't resolve within the specified milliseconds.
3
4
## Package Information
5
6
- **Package Name**: p-timeout
7
- **Package Type**: npm
8
- **Language**: JavaScript (ES modules) with TypeScript definitions
9
- **Installation**: `npm install p-timeout`
10
11
## Core Imports
12
13
```javascript
14
import pTimeout, { TimeoutError, AbortError } from 'p-timeout';
15
```
16
17
Individual imports:
18
19
```javascript
20
import { TimeoutError, AbortError } from 'p-timeout';
21
```
22
23
## Basic Usage
24
25
```javascript
26
import { setTimeout } from 'node:timers/promises';
27
import pTimeout from 'p-timeout';
28
29
const delayedPromise = setTimeout(200);
30
31
// Timeout after 50ms - will throw TimeoutError
32
await pTimeout(delayedPromise, {
33
milliseconds: 50,
34
});
35
//=> [TimeoutError: Promise timed out after 50 milliseconds]
36
```
37
38
## Capabilities
39
40
### Promise Timeout
41
42
Add timeout functionality to any promise with configurable error handling and cancellation support.
43
44
```javascript { .api }
45
/**
46
* Timeout a promise after a specified amount of time
47
* @param input - Promise to decorate
48
* @param options - Timeout configuration options
49
* @returns A decorated promise that times out after specified milliseconds with a .clear() method
50
*/
51
function pTimeout<ValueType, ReturnType = ValueType>(
52
input: PromiseLike<ValueType>,
53
options: Options<ReturnType>
54
): ClearablePromise<ValueType | ReturnType>;
55
56
// Special overload for message: false case
57
function pTimeout<ValueType, ReturnType = ValueType>(
58
input: PromiseLike<ValueType>,
59
options: Options<ReturnType> & {message: false}
60
): ClearablePromise<ValueType | ReturnType | undefined>;
61
```
62
63
**Usage Examples:**
64
65
```javascript
66
import pTimeout from 'p-timeout';
67
import { setTimeout } from 'node:timers/promises';
68
69
// Basic timeout
70
const result = await pTimeout(setTimeout(200, 'success'), {
71
milliseconds: 100, // Will timeout
72
});
73
74
// Custom error message
75
try {
76
await pTimeout(longRunningOperation(), {
77
milliseconds: 5000,
78
message: 'Operation took too long'
79
});
80
} catch (error) {
81
console.log(error.message); // 'Operation took too long'
82
}
83
84
// Silent timeout (resolves undefined instead of throwing)
85
const result = await pTimeout(slowPromise(), {
86
milliseconds: 1000,
87
message: false
88
});
89
// result will be undefined if timeout occurs
90
91
// Fallback function on timeout
92
const result = await pTimeout(unreliableAPI(), {
93
milliseconds: 3000,
94
fallback: () => 'default value'
95
});
96
97
// Clear timeout manually
98
const timeoutPromise = pTimeout(operation(), { milliseconds: 5000 });
99
// Later... cancel the timeout
100
timeoutPromise.clear();
101
```
102
103
### AbortController Integration
104
105
Support for modern cancellation using AbortController signals.
106
107
```javascript { .api }
108
// AbortController support through options.signal
109
interface Options<ReturnType> {
110
signal?: AbortSignal;
111
// ... other options
112
}
113
```
114
115
**Usage Example:**
116
117
```javascript
118
import pTimeout from 'p-timeout';
119
120
const delayedPromise = new Promise(resolve => setTimeout(resolve, 3000));
121
122
const abortController = new AbortController();
123
124
// Cancel after 100ms
125
setTimeout(() => {
126
abortController.abort();
127
}, 100);
128
129
await pTimeout(delayedPromise, {
130
milliseconds: 2000,
131
signal: abortController.signal
132
});
133
// Will throw AbortError or DOMException after 100ms
134
```
135
136
### Error Classes
137
138
Custom error classes for different timeout and cancellation scenarios.
139
140
```javascript { .api }
141
/**
142
* Error thrown when a promise times out
143
*/
144
class TimeoutError extends Error {
145
readonly name: 'TimeoutError';
146
constructor(message?: string);
147
}
148
149
/**
150
* Error thrown when request is aborted by AbortController
151
* (fallback when DOMException not available)
152
*/
153
class AbortError extends Error {
154
readonly name: 'AbortError';
155
constructor(message?: string);
156
}
157
```
158
159
**Usage Example:**
160
161
```javascript
162
import pTimeout, { TimeoutError } from 'p-timeout';
163
164
try {
165
await pTimeout(slowOperation(), { milliseconds: 1000 });
166
} catch (error) {
167
if (error instanceof TimeoutError) {
168
console.log('Operation timed out');
169
}
170
}
171
172
// Custom error subclassing
173
class MyCustomError extends TimeoutError {
174
name = "MyCustomError";
175
}
176
177
await pTimeout(operation(), {
178
milliseconds: 5000,
179
message: new MyCustomError('Custom timeout message')
180
});
181
```
182
183
### Testing Support
184
185
Custom timer implementations for testing scenarios and fake timer compatibility.
186
187
```javascript { .api }
188
interface Options<ReturnType> {
189
customTimers?: {
190
setTimeout: typeof globalThis.setTimeout;
191
clearTimeout: typeof globalThis.clearTimeout;
192
};
193
// ... other options
194
}
195
```
196
197
**Usage Example:**
198
199
```javascript
200
import pTimeout from 'p-timeout';
201
import sinon from 'sinon';
202
203
const originalSetTimeout = setTimeout;
204
const originalClearTimeout = clearTimeout;
205
206
sinon.useFakeTimers();
207
208
// Use pTimeout without being affected by sinon.useFakeTimers()
209
await pTimeout(doSomething(), {
210
milliseconds: 2000,
211
customTimers: {
212
setTimeout: originalSetTimeout,
213
clearTimeout: originalClearTimeout
214
}
215
});
216
```
217
218
### Cancelable Promise Support
219
220
Automatic integration with promises that have a `.cancel()` method.
221
222
```javascript { .api }
223
// When input promise has .cancel() method, it will be called on timeout
224
// No special API required - works automatically
225
```
226
227
**Usage Example:**
228
229
```javascript
230
import pTimeout from 'p-timeout';
231
import PCancelable from 'p-cancelable';
232
233
const cancelablePromise = new PCancelable((resolve, reject, onCancel) => {
234
const timeoutId = setTimeout(resolve, 5000);
235
onCancel(() => {
236
clearTimeout(timeoutId);
237
reject(new Error('Canceled'));
238
});
239
});
240
241
// If timeout occurs, cancelablePromise.cancel() will be called automatically
242
await pTimeout(cancelablePromise, { milliseconds: 1000 });
243
```
244
245
## Types
246
247
```javascript { .api }
248
/**
249
* Promise with additional clear() method to cancel timeout
250
*/
251
type ClearablePromise<T> = {
252
clear: () => void;
253
} & Promise<T>;
254
255
/**
256
* Configuration options for pTimeout function
257
*/
258
interface Options<ReturnType> {
259
/** Milliseconds before timing out (required) */
260
milliseconds: number;
261
262
/** Custom error message, error to throw, or false to resolve undefined */
263
message?: string | Error | false;
264
265
/** Function to call on timeout instead of rejecting */
266
fallback?: () => ReturnType | Promise<ReturnType>;
267
268
/** Custom timer implementations for testing */
269
readonly customTimers?: {
270
setTimeout: typeof globalThis.setTimeout;
271
clearTimeout: typeof globalThis.clearTimeout;
272
};
273
274
/** AbortController signal for cancellation */
275
signal?: globalThis.AbortSignal;
276
}
277
```
278
279
## Special Behaviors
280
281
- **Infinity milliseconds**: Passing `Infinity` will cause it to never time out
282
- **Invalid milliseconds**: Negative numbers or non-numbers throw `TypeError`
283
- **Pre-aborted signals**: If signal is already aborted, promise rejects immediately
284
- **Environment compatibility**: Uses `DOMException` when available, falls back to `AbortError`
285
- **Promise cancellation**: Automatically calls `.cancel()` method on cancelable promises during timeout
286
- **Zero dependencies**: Pure JavaScript with no runtime dependencies