/** * Cancelable promises * * https://stackoverflow.com/questions/46461801/possible-to-add-a-cancel-method-to-promise-in-typescript/46464377#46464377 */ export class Canceled extends Error { silent = false constructor(reason, silent = false) { super(reason) this.silent = silent Object.setPrototypeOf(this, Canceled.prototype) } } export interface Cancelable extends Promise { cancel(reason?: string, silent?: boolean): Cancelable } export function cancelable( promise: Promise, onCancel?: (canceled: Canceled) => void ): Cancelable { let cancel: ((reason: string, silent: boolean) => Cancelable) | null = null const cancelable: Cancelable = >new Promise((resolve, reject) => { cancel = (reason = '', silent = false) => { try { if (onCancel) { onCancel(new Canceled(reason, silent)) } } catch (e) { reject(e) } return cancelable } promise.then(resolve, reject) }) if (cancel) { cancelable.cancel = cancel } return cancelable }