codekingpro/portable-devtools
114k
1'use strict';2 3import CanceledError from './CanceledError.js';4 5/**6 * A `CancelToken` is an object that can be used to request cancellation of an operation.7 *8 * @param {Function} executor The executor function.9 *10 * @returns {CancelToken}11 */12class CancelToken {13 constructor(executor) {14 if (typeof executor !== 'function') {15 throw new TypeError('executor must be a function.');16 }17 18 let resolvePromise;19 20 this.promise = new Promise(function promiseExecutor(resolve) {21 resolvePromise = resolve;22 });23 24 const token = this;25 26 // eslint-disable-next-line func-names27 this.promise.then(cancel => {28 if (!token._listeners) return;29 30 let i = token._listeners.length;31 32 while (i-- > 0) {33 token._listeners[i](cancel);34 }35 token._listeners = null;36 });37 38 // eslint-disable-next-line func-names39 this.promise.then = onfulfilled => {40 let _resolve;41 // eslint-disable-next-line func-names42 const promise = new Promise(resolve => {43 token.subscribe(resolve);44 _resolve = resolve;45 }).then(onfulfilled);46 47 promise.cancel = function reject() {48 token.unsubscribe(_resolve);49 };50 51 return promise;52 };53 54 executor(function cancel(message, config, request) {55 if (token.reason) {56 // Cancellation has already been requested57 return;58 }59 60 token.reason = new CanceledError(message, config, request);61 resolvePromise(token.reason);62 });63 }64 65 /**66 * Throws a `CanceledError` if cancellation has been requested.67 */68 throwIfRequested() {69 if (this.reason) {70 throw this.reason;71 }72 }73 74 /**75 * Subscribe to the cancel signal76 */77 78 subscribe(listener) {79 if (this.reason) {80 listener(this.reason);81 return;82 }83 84 if (this._listeners) {85 this._listeners.push(listener);86 } else {87 this._listeners = [listener];88 }89 }90 91 /**92 * Unsubscribe from the cancel signal93 */94 95 unsubscribe(listener) {96 if (!this._listeners) {97 return;98 }99 const index = this._listeners.indexOf(listener);100 if (index !== -1) {101 this._listeners.splice(index, 1);102 }103 }104 105 /**106 * Returns an object that contains a new `CancelToken` and a function that, when called,107 * cancels the `CancelToken`.108 */109 static source() {110 let cancel;111 const token = new CancelToken(function executor(c) {112 cancel = c;113 });114 return {115 token,116 cancel117 };118 }119}120 121export default CancelToken;122 