Created
August 3, 2018 08:59
-
-
Save tjmw/843b1e96ce9f4d942b6521562a75e1e7 to your computer and use it in GitHub Desktop.
Promise Retry
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @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 }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @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