composeSignals.js 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. import CanceledError from "../cancel/CanceledError.js";
  2. import AxiosError from "../core/AxiosError.js";
  3. import utils from '../utils.js';
  4. const composeSignals = (signals, timeout) => {
  5. const {length} = (signals = signals ? signals.filter(Boolean) : []);
  6. if (timeout || length) {
  7. let controller = new AbortController();
  8. let aborted;
  9. const onabort = function (reason) {
  10. if (!aborted) {
  11. aborted = true;
  12. unsubscribe();
  13. const err = reason instanceof Error ? reason : this.reason;
  14. controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err));
  15. }
  16. }
  17. let timer = timeout && setTimeout(() => {
  18. timer = null;
  19. onabort(new AxiosError(`timeout ${timeout} of ms exceeded`, AxiosError.ETIMEDOUT))
  20. }, timeout)
  21. const unsubscribe = () => {
  22. if (signals) {
  23. timer && clearTimeout(timer);
  24. timer = null;
  25. signals.forEach(signal => {
  26. signal.unsubscribe ? signal.unsubscribe(onabort) : signal.removeEventListener('abort', onabort);
  27. });
  28. signals = null;
  29. }
  30. }
  31. signals.forEach((signal) => signal.addEventListener('abort', onabort));
  32. const {signal} = controller;
  33. signal.unsubscribe = () => utils.asap(unsubscribe);
  34. return signal;
  35. }
  36. }
  37. export default composeSignals;