bb41b6aaecb482307525707b171c0124de6f4e1276b6a0a0e8912f1901ec9b5367a67ae70cd6c92b99e5ba5bfc6a80e9b1f9d3ef2637fe374da9b33d1b025a 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. 'use strict';
  2. var CanceledError = require('./CanceledError');
  3. /**
  4. * A `CancelToken` is an object that can be used to request cancellation of an operation.
  5. *
  6. * @class
  7. * @param {Function} executor The executor function.
  8. */
  9. function CancelToken(executor) {
  10. if (typeof executor !== 'function') {
  11. throw new TypeError('executor must be a function.');
  12. }
  13. var resolvePromise;
  14. this.promise = new Promise(function promiseExecutor(resolve) {
  15. resolvePromise = resolve;
  16. });
  17. var token = this;
  18. // eslint-disable-next-line func-names
  19. this.promise.then(function(cancel) {
  20. if (!token._listeners) return;
  21. var i = token._listeners.length;
  22. while (i-- > 0) {
  23. token._listeners[i](cancel);
  24. }
  25. token._listeners = null;
  26. });
  27. // eslint-disable-next-line func-names
  28. this.promise.then = function(onfulfilled) {
  29. var _resolve;
  30. // eslint-disable-next-line func-names
  31. var promise = new Promise(function(resolve) {
  32. token.subscribe(resolve);
  33. _resolve = resolve;
  34. }).then(onfulfilled);
  35. promise.cancel = function reject() {
  36. token.unsubscribe(_resolve);
  37. };
  38. return promise;
  39. };
  40. executor(function cancel(message, config, request) {
  41. if (token.reason) {
  42. // Cancellation has already been requested
  43. return;
  44. }
  45. token.reason = new CanceledError(message, config, request);
  46. resolvePromise(token.reason);
  47. });
  48. }
  49. /**
  50. * Throws a `CanceledError` if cancellation has been requested.
  51. */
  52. CancelToken.prototype.throwIfRequested = function throwIfRequested() {
  53. if (this.reason) {
  54. throw this.reason;
  55. }
  56. };
  57. /**
  58. * Subscribe to the cancel signal
  59. */
  60. CancelToken.prototype.subscribe = function subscribe(listener) {
  61. if (this.reason) {
  62. listener(this.reason);
  63. return;
  64. }
  65. if (this._listeners) {
  66. this._listeners.push(listener);
  67. } else {
  68. this._listeners = [listener];
  69. }
  70. };
  71. /**
  72. * Unsubscribe from the cancel signal
  73. */
  74. CancelToken.prototype.unsubscribe = function unsubscribe(listener) {
  75. if (!this._listeners) {
  76. return;
  77. }
  78. var index = this._listeners.indexOf(listener);
  79. if (index !== -1) {
  80. this._listeners.splice(index, 1);
  81. }
  82. };
  83. /**
  84. * Returns an object that contains a new `CancelToken` and a function that, when called,
  85. * cancels the `CancelToken`.
  86. */
  87. CancelToken.source = function source() {
  88. var cancel;
  89. var token = new CancelToken(function executor(c) {
  90. cancel = c;
  91. });
  92. return {
  93. token: token,
  94. cancel: cancel
  95. };
  96. };
  97. module.exports = CancelToken;