123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- 'use strict';
- const pFinally = require('p-finally');
- class TimeoutError extends Error {
- constructor(message) {
- super(message);
- this.name = 'TimeoutError';
- }
- }
- const pTimeout = (promise, milliseconds, fallback) => new Promise((resolve, reject) => {
- if (typeof milliseconds !== 'number' || milliseconds < 0) {
- throw new TypeError('Expected `milliseconds` to be a positive number');
- }
- if (milliseconds === Infinity) {
- resolve(promise);
- return;
- }
- const timer = setTimeout(() => {
- if (typeof fallback === 'function') {
- try {
- resolve(fallback());
- } catch (error) {
- reject(error);
- }
- return;
- }
- const message = typeof fallback === 'string' ? fallback : `Promise timed out after ${milliseconds} milliseconds`;
- const timeoutError = fallback instanceof Error ? fallback : new TimeoutError(message);
- if (typeof promise.cancel === 'function') {
- promise.cancel();
- }
- reject(timeoutError);
- }, milliseconds);
- // TODO: Use native `finally` keyword when targeting Node.js 10
- pFinally(
- // eslint-disable-next-line promise/prefer-await-to-then
- promise.then(resolve, reject),
- () => {
- clearTimeout(timer);
- }
- );
- });
- module.exports = pTimeout;
- // TODO: Remove this for the next major release
- module.exports.default = pTimeout;
- module.exports.TimeoutError = TimeoutError;
|