Skip to content

Commit 34e2ae4

Browse files
committed
simpler implementation
1 parent 873897e commit 34e2ae4

File tree

1 file changed

+30
-38
lines changed

1 file changed

+30
-38
lines changed

src/retrier.js

Lines changed: 30 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
const { isNumber } = require('./utilities')
2-
31
const createLinear = function (constants = {}) {
42
const { m = 1, b = 0 } = constants
53

@@ -27,49 +25,43 @@ const createExponential = function (constants = {}, m = 1) {
2725
module.exports.createExponential = createExponential
2826

2927
/**
30-
* @param {Function}
31-
* @param {Function|Number}
32-
* @param {Number}
33-
* @param {Function}
28+
* Wraps an `async` function for async retries as per the logic given in `curve`.
29+
* Curve is expected to be a callback which will be called at each failed
30+
* iteration with `err` (the error thrown by the wrapped function) and `count`
31+
* which is the count of total attempts to `resolve` - it should either throw
32+
* (should no more retries be required) or return an integer dictating the
33+
* number of milliseconds to sleep before re-attempting resolution.
34+
*
35+
* @param {Function} fn
36+
* @param {Function|Object} curve
3437
* @returns {Function}
3538
*/
36-
const createRetrierFn = function (fn, curve = 2, limit = 2, shouldRetry = undefined) {
37-
if (isNumber(curve)) {
38-
limit = curve
39-
curve = zero
39+
const createRetrierFn = function (fn, curve) {
40+
if (!curve) {
41+
curve = function (err, count) {
42+
if (count > 1) throw err
43+
return 0
44+
}
4045
}
4146

42-
return function () {
43-
const args = Array.prototype.slice.call(arguments)
44-
45-
return new Promise(function (resolve, reject) {
46-
(function recurse(attempt) {
47-
function retry(error) {
48-
const errorCount = attempt + 1
49-
50-
if (limit && errorCount >= limit) return reject(error)
51-
52-
if (shouldRetry && !shouldRetry(error)) return reject(error)
53-
54-
return recurse(errorCount)
47+
return function (...args) {
48+
let attempt = 0
49+
50+
const recurse = function (resolve, reject) {
51+
return fn(...args).then(resolve).catch(function (err) {
52+
let timeout = curve(err, ++attempt)
53+
if (timeout < 0) return reject(err)
54+
try {
55+
if (err <= 0) return recurse(resolve, reject)
56+
return setTimeout(recurse, timeout, resolve, reject)
57+
} catch (_err) {
58+
return reject(_err)
5559
}
60+
})
61+
}
5662

57-
setTimeout(function () {
58-
try {
59-
Promise
60-
.resolve(fn.apply(null, args))
61-
.then(resolve)
62-
.catch(function (asyncErr) {
63-
return retry(asyncErr)
64-
})
65-
} catch (syncErr) {
66-
retry(syncErr)
67-
}
68-
}, curve(attempt))
69-
}(null, 0))
70-
})
63+
return new Promise(recurse)
7164
}
7265
}
7366

74-
module.exports.retry = createRetrierFn
7567
module.exports.createRetrierFn = createRetrierFn

0 commit comments

Comments
 (0)