import { defer as rxjsDefer, retry } from 'rxjs'; export class RetryablePromise extends Promise { constructor( executor: ( resolve: (value: T | PromiseLike) => void, reject: (reason?: any) => void ) => void, retryTimes: number = 3, retryIntervalInMs: number = 300 ) { super((resolve, reject) => { rxjsDefer(() => new Promise(executor)) .pipe( retry({ count: retryTimes, delay: retryIntervalInMs, }) ) .subscribe({ next: v => { resolve(v); }, error: e => { reject(e); }, }); }); } } export function retryable( asyncFn: () => Promise, retryTimes = 3, retryIntervalInMs = 300 ): Promise { return new RetryablePromise( (resolve, reject) => { asyncFn().then(resolve).catch(reject); }, retryTimes, retryIntervalInMs ); } export function defer(dispose: () => Promise) { return { [Symbol.asyncDispose]: dispose, }; }