UNPKG

@freemework/common

Version:

Common library of the Freemework Project.

66 lines (57 loc) 2.05 kB
import { FException, FExceptionAggregate } from "../exception/index.js"; import { FCancellationException } from "./f_cancellation_exception.js"; import { FCancellationToken } from "./f_cancellation_token.js"; import { FCancellationTokenSource } from "./f_cancellation_token_source.js"; export class FCancellationTokenSourceManual implements FCancellationTokenSource { private readonly _token: FCancellationToken; private readonly _cancelListeners: Array<Function> = []; private _isCancellationRequested: boolean; public constructor() { this._isCancellationRequested = false; const self = this; this._token = { get isCancellationRequested() { return self.isCancellationRequested; }, addCancelListener(cb) { self.addCancelListener(cb); }, removeCancelListener(cb) { self.removeCancelListener(cb); }, throwIfCancellationRequested() { self.throwIfCancellationRequested(); } }; } public get token(): FCancellationToken { return this._token; } public get isCancellationRequested(): boolean { return this._isCancellationRequested; } public cancel(): void { if (this._isCancellationRequested) { // Prevent to call listeners twice return; } this._isCancellationRequested = true; const errors: Array<FException> = []; if (this._cancelListeners.length > 0) { // Release callback. We do not need its anymore const cancelListeners = this._cancelListeners.splice(0); cancelListeners.forEach(cancelListener => { try { cancelListener(); } catch (e) { errors.push(FException.wrapIfNeeded(e)); } }); } if (errors.length > 0) { throw new FExceptionAggregate(errors); } } private addCancelListener(cb: Function): void { this._cancelListeners.push(cb); } private removeCancelListener(cb: Function): void { const cbIndex = this._cancelListeners.indexOf(cb); if (cbIndex !== -1) { this._cancelListeners.splice(cbIndex, 1); } } private throwIfCancellationRequested(): void { if (this.isCancellationRequested) { throw new FCancellationException(); } } }