UNPKG

windmill-utils-internal

Version:

Internal utility functions for Windmill

96 lines (95 loc) 2.95 kB
export class CancelError extends Error { constructor(message) { super(message); this.name = 'CancelError'; } get isCancelled() { return true; } } export class CancelablePromise { _isResolved; _isRejected; _isCancelled; cancelHandlers; promise; _resolve; _reject; constructor(executor) { this._isResolved = false; this._isRejected = false; this._isCancelled = false; this.cancelHandlers = []; this.promise = new Promise((resolve, reject) => { this._resolve = resolve; this._reject = reject; const onResolve = (value) => { if (this._isResolved || this._isRejected || this._isCancelled) { return; } this._isResolved = true; if (this._resolve) this._resolve(value); }; const onReject = (reason) => { if (this._isResolved || this._isRejected || this._isCancelled) { return; } this._isRejected = true; if (this._reject) this._reject(reason); }; const onCancel = (cancelHandler) => { if (this._isResolved || this._isRejected || this._isCancelled) { return; } this.cancelHandlers.push(cancelHandler); }; Object.defineProperty(onCancel, 'isResolved', { get: () => this._isResolved, }); Object.defineProperty(onCancel, 'isRejected', { get: () => this._isRejected, }); Object.defineProperty(onCancel, 'isCancelled', { get: () => this._isCancelled, }); return executor(onResolve, onReject, onCancel); }); } get [Symbol.toStringTag]() { return "Cancellable Promise"; } then(onFulfilled, onRejected) { return this.promise.then(onFulfilled, onRejected); } catch(onRejected) { return this.promise.catch(onRejected); } finally(onFinally) { return this.promise.finally(onFinally); } cancel() { if (this._isResolved || this._isRejected || this._isCancelled) { return; } this._isCancelled = true; if (this.cancelHandlers.length) { try { for (const cancelHandler of this.cancelHandlers) { cancelHandler(); } } catch (error) { console.warn('Cancellation threw an error', error); return; } } this.cancelHandlers.length = 0; if (this._reject) this._reject(new CancelError('Request aborted')); } get isCancelled() { return this._isCancelled; } }