123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- 'use strict';
- import CanceledError from './CanceledError.js';
- /**
- * A `CancelToken` is an object that can be used to request cancellation of an operation.
- *
- * @param {Function} executor The executor function.
- *
- * @returns {CancelToken}
- */
- class CancelToken {
- constructor(executor) {
- if (typeof executor !== 'function') {
- throw new TypeError('executor must be a function.');
- }
- let resolvePromise;
- this.promise = new Promise(function promiseExecutor(resolve) {
- resolvePromise = resolve;
- });
- const token = this;
- // eslint-disable-next-line func-names
- this.promise.then(cancel => {
- if (!token._listeners) return;
- let i = token._listeners.length;
- while (i-- > 0) {
- token._listeners[i](cancel);
- }
- token._listeners = null;
- });
- // eslint-disable-next-line func-names
- this.promise.then = onfulfilled => {
- let _resolve;
- // eslint-disable-next-line func-names
- const promise = new Promise(resolve => {
- token.subscribe(resolve);
- _resolve = resolve;
- }).then(onfulfilled);
- promise.cancel = function reject() {
- token.unsubscribe(_resolve);
- };
- return promise;
- };
- executor(function cancel(message, config, request) {
- if (token.reason) {
- // Cancellation has already been requested
- return;
- }
- token.reason = new CanceledError(message, config, request);
- resolvePromise(token.reason);
- });
- }
- /**
- * Throws a `CanceledError` if cancellation has been requested.
- */
- throwIfRequested() {
- if (this.reason) {
- throw this.reason;
- }
- }
- /**
- * Subscribe to the cancel signal
- */
- subscribe(listener) {
- if (this.reason) {
- listener(this.reason);
- return;
- }
- if (this._listeners) {
- this._listeners.push(listener);
- } else {
- this._listeners = [listener];
- }
- }
- /**
- * Unsubscribe from the cancel signal
- */
- unsubscribe(listener) {
- if (!this._listeners) {
- return;
- }
- const index = this._listeners.indexOf(listener);
- if (index !== -1) {
- this._listeners.splice(index, 1);
- }
- }
- toAbortSignal() {
- const controller = new AbortController();
- const abort = (err) => {
- controller.abort(err);
- };
- this.subscribe(abort);
- controller.signal.unsubscribe = () => this.unsubscribe(abort);
- return controller.signal;
- }
- /**
- * Returns an object that contains a new `CancelToken` and a function that, when called,
- * cancels the `CancelToken`.
- */
- static source() {
- let cancel;
- const token = new CancelToken(function executor(c) {
- cancel = c;
- });
- return {
- token,
- cancel
- };
- }
- }
- export default CancelToken;
|