UNPKG

tryloop

Version:

Simple library for retrying operations, it supports multiple backoff strategies.

82 lines (81 loc) 2.35 kB
/* IMPORT */ import { isPromise, isUndefined } from '../utils.js'; /* MAIN */ class Abstract { /* CONSTRUCTOR */ constructor(options) { this.running = false; this.startTime = NaN; this.stopTime = NaN; this.tries = 0; this.options = Object.assign({ timeout: Infinity, tries: Infinity }, options); //TSC: not sure what to do about the supposed error this.options.timeout = Math.min(2147483647, this.options.timeout); } /* API */ start() { if (this.running) return this.result; this.running = true; this.startTime = Date.now(); this.tries = 0; this.result = this.loop(); return this.result; } stop() { if (!this.running) return; this.running = false; this.stopTime = Date.now(); } cancel() { return this.stop(); } loop() { let timeoutId; return Promise.race([ new Promise(resolve => { if (this.options.timeout === Infinity) return; timeoutId = setTimeout(() => { this.stop(); resolve(undefined); }, this.options.timeout); }), new Promise(res => { const resolve = value => { clearTimeout(timeoutId); this.stop(); res(value); }; const retry = () => this.schedule(attempt); const attempt = () => this.try(resolve, retry); attempt(); }) ]); } try(resolve, retry) { if (!this.running) return resolve(); if ((Date.now() - this.startTime) >= this.options.timeout) return resolve(); if (this.tries >= this.options.tries) return resolve(); this.tries++; const onResult = result => isUndefined(result) ? retry() : resolve(result); const result = this.options.fn(); if (isPromise(result)) { result.then(onResult); } else { onResult(result); } } schedule(_) { throw new Error('Missing schedule function'); } } /* EXPORT */ export default Abstract;