63 lines
1.5 KiB
TypeScript
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;
|
||
|
}
|