tweb/src/helpers/cancellablePromise.ts

63 lines
1.5 KiB
TypeScript

export interface CancellablePromise<T> extends Promise<T> {
resolve?: (...args: any[]) => void,
reject?: (...args: any[]) => void,
cancel?: () => void,
notify?: (...args: any[]) => void,
notifyAll?: (...args: any[]) => void,
lastNotify?: any,
listeners?: Array<(...args: any[]) => void>,
addNotifyListener?: (callback: (...args: any[]) => void) => void,
isFulfilled?: boolean,
isRejected?: boolean
}
export function deferredPromise<T>() {
let deferredHelper: any = {
isFulfilled: false,
isRejected: false,
notify: () => {},
notifyAll: (...args: any[]) => {
deferredHelper.lastNotify = args;
deferredHelper.listeners.forEach((callback: any) => callback(...args));
},
lastNotify: undefined,
listeners: [],
addNotifyListener: (callback: (...args: any[]) => void) => {
if(deferredHelper.lastNotify) {
callback(...deferredHelper.lastNotify);
}
deferredHelper.listeners.push(callback);
}
};
let deferred: CancellablePromise<T> = new Promise<T>((resolve, reject) => {
deferredHelper.resolve = (value: T) => {
if(deferred.isFulfilled) return;
deferred.isFulfilled = true;
resolve(value);
};
deferredHelper.reject = (...args: any[]) => {
if(deferred.isRejected) return;
deferred.isRejected = true;
reject(...args);
};
});
deferred.finally(() => {
deferred.notify = null;
deferred.listeners.length = 0;
deferred.lastNotify = null;
});
Object.assign(deferred, deferredHelper);
return deferred;
}