await-timeout v1.1.1
Contents
Installation
npm install await-timeout --saveUsage
Just wait some time:
import Timeout from 'await-timeout'; // wait 1000 ms and resolve await Timeout.set(1000); // wait 1000 ms and reject with 'Timeout!' await Timeout.set(1000, 'Timeout!');Use
Timeoutinstance insidetry...finallyblock to make proper cleanup:import Timeout from 'await-timeout'; const timer = new Timeout(); try { await Promise.race([ fetch('https://example.com'), timer.set(1000, 'Timeout!') ]); } finally { timer.clear(); }Without a timer cleanup you may get unexpected effects in you code - as all promises in
Promise.raceare get fulfilled.
API
new Timeout()
Constructs new timeout instance. It does not start timer but creates variable for timer manipulation.
const timer = new Timeout();Note: having separate
timervariable is useful for clearing timeout infinallyblock
.set(delay, rejectReason) ⇒ Promise
Starts new timer like setTimeout() and returns promise. The promise will be resolved after delay milliseconds:
const timer = new Timeout();
timer.set(1000)
.then(() => console.log('1000 ms passed.'));If you provide rejectReason - a timer promise will be rejected with specified reason:
// rejects with Error: Timeout after 1000 ms:
timer.set(1000, 'Timeout after 1000 ms');
// above is actually shortcut for:
timer.set(1000).then(() => Promise.reject(new Error('Timeout after 1000 ms'))); If you need to just wait some time - use static version of .set():
await Timeout.set(1000);.wrap(promise, delay, rejectReason) ⇒ Promise
Wraps existing promise with timeout:
- returned promise automatically rejected after timeout
- timeout automatically cleared if main promise resolves first
async function fetchWithTimeout() {
const promise = fetch('https://example.com');
return Timeout.wrap(promise, 1000, 'Timeout');
}Actually it is a shortcut for:
async function fetchWithTimeout() {
const timer = new Timeout();
try {
const promise = fetch('https://example.com');
return await Promise.race([
promise,
timer.set(1000, 'Timeout')
]);
} finally {
timer.clear();
}
}.clear()
Clears existing timeout like clearTimeout().
const timer = new Timeout();
timer.set(1000)
.then(() => console.log('This will never be called, because timeout is cleared on the next line'));
timer.clear();With ES7 async / await .clear() can be used in finally block:
async function foo() {
const timer = new Timeout();
try {
// some async stuff
} finally {
timer.clear();
}
}.id ⇒ ?Number|?Timeout
Returns result of setTimeout call. That is Number timeout id in browser
and Timeout instance in Node.js.
.delay ⇒ ?Number
Returns last delay value used. Delay is useful for generating reject reason:
const timer = new Timeout();
timer.set(1000, () => new Error(`Timeout: ${timer.delay}`));Motivation
Before making this library I've researched several similar packages on Npm. But no one satisfied all my needs together:
- Convenient way to cancel timeout. I typically use it with Promise.race() and don't want timer to trigger if main promise is resolved first.
- API similar to
setTimeout/clearTimeout. I get used to these functions and would like to have mirror syntax. - Easy rejection of timeout promise. Passing error message should be enough.
- No monkey-patching of Promise object.
- Zero dependencies.
Related resources
- The right way to clear timeout in Promise.race()
- Applying a timeout to your promises
- How to make a promise from setTimeout
- Is there a version of setTimeout that returns an ES6 promise?
License
MIT @ Vitaliy Potapov