https://github.com/tim-kos/node-retry (npm install retry)
const retry = require('retry') const delay = require('delay') const isItGood = [false, false, true] let numAttempt = 0 function retryer() { let operation = retry.operation() return new Promise((resolve, reject) => { operation.attempt(async currentAttempt => { console.log('Attempt #:', numAttempt) await delay(2000) const err = !isItGood[numAttempt] ? true : null if (operation.retry(err)) { numAttempt++ return } if (isItGood[numAttempt]) { resolve('All good!') } else { reject(operation.mainError()) } }) }) } async function main() { console.log('Start') await retryer() console.log('End') } main()
import * as retry from 'retry' const fnName = () => { const operation = retry.operation({ retries: 3, // 重试3次 minTimeout: 0 }); nextTick(() => { operation.attempt(async (currentAttempt) => { setTimeout(async () => { try { //todo 异步函数 operation.stop(); } catch (error) { if (!operation.retry(new Error())) { // 已达到最大返回数量 console.log(`超过最大重试次数-----${currentAttempt}`) } } }, (currentAttempt == 1 ? 0 : 2000)) // 第一次 不需要延时 }) }); }
API
retry.operation([options])
Creates a new RetryOperation
object. options
is the same as retry.timeouts()
's options
, with three additions:
forever
: Whether to retry forever, defaults tofalse
.unref
: Whether to unref the setTimeout's, defaults tofalse
.maxRetryTime
: The maximum time (in milliseconds) that the retried operation is allowed to run. Default isInfinity
.
retry.timeouts([options])
Returns an array of timeouts. All time options
and return values are in milliseconds. If options
is an array, a copy of that array is returned.
options
is a JS object that can contain any of the following keys:
retries
: The maximum amount of times to retry the operation. Default is10
. Seting this to1
meansdo it once, then retry it once
.factor
: The exponential factor to use. Default is2
.minTimeout
: The number of milliseconds before starting the first retry. Default is1000
.maxTimeout
: The maximum number of milliseconds between two retries. Default isInfinity
.randomize
: Randomizes the timeouts by multiplying with a factor between1
to2
. Default isfalse
.
The formula used to calculate the individual timeouts is:
Math.min(random * minTimeout * Math.pow(factor, attempt), maxTimeout)
Have a look at this article for a better explanation of approach.
If you want to tune your factor
/ times
settings to attempt the last retry after a certain amount of time, you can use wolfram alpha. For example in order to tune for 10
attempts in 5 minutes
, you can use this equation:
Explaining the various values from left to right:
k = 0 ... 9
: Theretries
value (10)1000
: TheminTimeout
value in ms (1000)x^k
: No need to change this,x
will be your resulting factor5 * 60 * 1000
: The desired total amount of time for retrying in ms (5 minutes)
To make this a little easier for you, use wolfram alpha to do the calculations:
http://www.wolframalpha.com/input/?i=Sum%5B1000*x^k%2C+{k%2C+0%2C+9}%5D+%3D+5+*+60+*+1000
retry.createTimeout(attempt, opts)
Returns a new timeout
(integer in milliseconds) based on the given parameters.
attempt
is an integer representing for which retry the timeout should be calculated. If your retry operation was executed 4 times you had one attempt and 3 retries. If you then want to calculate a new timeout, you should set attempt
to 4 (attempts are zero-indexed).
opts
can include factor
, minTimeout
, randomize
(boolean) and maxTimeout
. They are documented above.
retry.createTimeout()
is used internally by retry.timeouts()
and is public for you to be able to create your own timeouts for reinserting an item, see issue #13.
retry.wrap(obj, [options], [methodNames])
Wrap all functions of the obj
with retry. Optionally you can pass operation options and an array of method names which need to be wrapped.
retry.wrap(obj)
retry.wrap(obj, ['method1', 'method2'])
retry.wrap(obj, {retries: 3})
retry.wrap(obj, {retries: 3}, ['method1', 'method2'])
The options
object can take any options that the usual call to retry.operation
can take.
new RetryOperation(timeouts, [options])
Creates a new RetryOperation
where timeouts
is an array where each value is a timeout given in milliseconds.
Available options:
forever
: Whether to retry forever, defaults tofalse
.unref
: Wether to unref the setTimeout's, defaults tofalse
.
If forever
is true, the following changes happen:
RetryOperation.errors()
will only output an array of one item: the last error.RetryOperation
will repeatedly use thetimeouts
array. Once all of its timeouts have been used up, it restarts with the first timeout, then uses the second and so on.
retryOperation.errors()
Returns an array of all errors that have been passed to retryOperation.retry()
so far. The returning array has the errors ordered chronologically based on when they were passed to retryOperation.retry()
, which means the first passed error is at index zero and the last is at the last index.
retryOperation.mainError()
A reference to the error object that occured most frequently. Errors are compared using the error.message
property.
If multiple error messages occured the same amount of time, the last error object with that message is returned.
If no errors occured so far, the value is null
.
retryOperation.attempt(fn, timeoutOps)
Defines the function fn
that is to be retried and executes it for the first time right away. The fn
function can receive an optional currentAttempt
callback that represents the number of attempts to execute fn
so far.
Optionally defines timeoutOps
which is an object having a property timeout
in miliseconds and a property cb
callback function. Whenever your retry operation takes longer than timeout
to execute, the timeout callback function cb
is called.
retryOperation.try(fn)
This is an alias for retryOperation.attempt(fn)
. This is deprecated. Please use retryOperation.attempt(fn)
instead.
retryOperation.start(fn)
This is an alias for retryOperation.attempt(fn)
. This is deprecated. Please use retryOperation.attempt(fn)
instead.
retryOperation.retry(error)
Returns false
when no error
value is given, or the maximum amount of retries has been reached.
Otherwise it returns true
, and retries the operation after the timeout for the current attempt number.
retryOperation.stop()
Allows you to stop the operation being retried. Useful for aborting the operation on a fatal error etc.
retryOperation.reset()
Resets the internal state of the operation object, so that you can call attempt()
again as if this was a new operation object.
retryOperation.attempts()
Returns an int representing the number of attempts it took to call fn
before it was successful.
标签:node,retry,attempt,retryOperation,operation,异常,options,fn From: https://www.cnblogs.com/sybboy/p/16825380.html