index.js 939 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. 'use strict';
  2. const pFinally = require('p-finally');
  3. class TimeoutError extends Error {
  4. constructor(message) {
  5. super(message);
  6. this.name = 'TimeoutError';
  7. }
  8. }
  9. module.exports = (promise, ms, fallback) => new Promise((resolve, reject) => {
  10. if (typeof ms !== 'number' || ms < 0) {
  11. throw new TypeError('Expected `ms` to be a positive number');
  12. }
  13. const timer = setTimeout(() => {
  14. if (typeof fallback === 'function') {
  15. try {
  16. resolve(fallback());
  17. } catch (err) {
  18. reject(err);
  19. }
  20. return;
  21. }
  22. const message = typeof fallback === 'string' ? fallback : `Promise timed out after ${ms} milliseconds`;
  23. const err = fallback instanceof Error ? fallback : new TimeoutError(message);
  24. if (typeof promise.cancel === 'function') {
  25. promise.cancel();
  26. }
  27. reject(err);
  28. }, ms);
  29. pFinally(
  30. promise.then(resolve, reject),
  31. () => {
  32. clearTimeout(timer);
  33. }
  34. );
  35. });
  36. module.exports.TimeoutError = TimeoutError;