Skip to content

Instantly share code, notes, and snippets.

@tjmw
Created August 3, 2018 08:59
Show Gist options
  • Save tjmw/843b1e96ce9f4d942b6521562a75e1e7 to your computer and use it in GitHub Desktop.
Save tjmw/843b1e96ce9f4d942b6521562a75e1e7 to your computer and use it in GitHub Desktop.
Promise Retry
// @flow
class PromiseRetryer {
fn: () => Promise<*>;
maxTryCount: number;
retryDelay: number;
tries: number;
constructor(fn: () => Promise<*>, maxTryCount: number, retryDelay: number) {
this.fn = fn;
this.maxTryCount = maxTryCount;
this.retryDelay = retryDelay;
this.tries = 0;
}
run(): Promise<*> {
return this.fn().catch(e => {
this.tries++;
if (this.tries < this.maxTryCount) {
return new Promise((resolve, reject) =>
setTimeout(
() =>
this.run()
.then(resolve)
.catch(reject),
this.retryDelay
)
);
} else {
throw e;
}
});
}
}
export { PromiseRetryer };
// @flow
import { PromiseRetryer } from "../promise-retryer";
describe("PromiseRetryer", () => {
it("tries once if the function returns a resolved promise first time", () => {
expect.assertions(1);
let counter = 0;
const fn = () => {
counter++;
return Promise.resolve();
};
const maxTryCount = 5;
const retryer = new PromiseRetryer(fn, maxTryCount, 0);
return retryer.run().then(() => {
expect(counter).toEqual(1);
});
});
it("retries if the function fails (returns a rejected promise)", () => {
expect.assertions(1);
let counter = 0;
let results = [Promise.reject(), Promise.reject(), Promise.resolve()];
const fn = () => {
counter++;
return results.shift();
};
const maxTryCount = 5;
const retryer = new PromiseRetryer(fn, maxTryCount, 0);
return retryer.run().then(() => {
expect(counter).toEqual(3);
});
});
it("retries the function up to the configured maximum if the function keeps failing", () => {
expect.assertions(1);
let counter = 0;
let results = [
Promise.reject(),
Promise.reject(),
Promise.reject(),
Promise.reject(),
Promise.resolve(),
];
const fn = () => {
counter++;
return results.shift();
};
const maxTryCount = 5;
const retryer = new PromiseRetryer(fn, maxTryCount, 0);
return retryer.run().then(() => {
expect(counter).toEqual(5);
});
});
it("does not exceed the configured maximum if the function keeps failing", () => {
expect.assertions(1);
let counter = 0;
let results = [
Promise.reject(),
Promise.reject(),
Promise.reject(),
Promise.reject(),
Promise.reject(),
Promise.reject(),
Promise.reject(),
];
const fn = () => {
counter++;
return results.shift();
};
const maxTryCount = 5;
const retryer = new PromiseRetryer(fn, maxTryCount, 0);
return retryer.run().catch(() => {
expect(counter).toEqual(5);
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment