123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- "use strict";
- var __importDefault = (this && this.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
- };
- Object.defineProperty(exports, "__esModule", { value: true });
- const retry_1 = __importDefault(require("retry"));
- // import { RetryOperation } from 'retry/lib/retry_operation'
- const RetryOperation = require('retry/lib/retry_operation');
- /* istanbul ignore next */
- function defaultShouldRetry(e, result) {
- return { retryAble: false, message: '' };
- }
- /**
- * withRetry 重试封装函数
- * @param fn
- * @param retryOptions
- */
- /* istanbul ignore next */
- function withRetry(fn, retryOptions) {
- // 默认不重试,0 表达未开启的含义,所以直接返回 promise
- if (!retryOptions || retryOptions.retries === 0) {
- return fn();
- }
- // 默认重试策略采取指数退避策略,超时时间计算公式及参数可查文档
- // https://github.com/tim-kos/node-retry/
- // 自定重试时间:
- // timeouts: [1000, 2000, 4000, 8000]
- const timeouts = retryOptions.timeouts
- ? [...retryOptions.timeouts]
- : retry_1.default.timeouts(retryOptions);
- const operation = new RetryOperation(timeouts, {
- forever: retryOptions.forever,
- unref: retryOptions.unref,
- maxRetryTime: retryOptions.maxRetryTime // 重试总的时间,单位毫秒,默认:Infinity
- });
- const shouldRetry = retryOptions.shouldRetry || defaultShouldRetry;
- return new Promise((resolve, reject) => {
- const isReadyToRetry = (e, resp, operation) => {
- // 外层有效识别需要或者能够进行重试
- // shouldRetry 中可调用 operation.stop 停掉重试,operation.retry 返回 false
- const { retryAble, message } = shouldRetry(e, resp, operation);
- const info = {};
- info.nth = operation.attempts();
- info.at = new Date();
- info.message = message;
- // 双重条件判断是否重试,外层判断满足条件与否,还需判断是否满足再次重试条件
- const readyToRetry = retryAble && operation.retry(Object.assign({}, info));
- if (!readyToRetry) {
- // 如果不准备进行重试,并且尝试不止一次
- // 最后一个错误记录重试信息
- const ref = e || resp;
- if (ref && operation.attempts() > 1) {
- ref.attempt = {};
- ref.attempt.timeouts = operation._originalTimeouts;
- ref.attempt.attempts = operation.attempts();
- ref.attempt.errors = operation.errors();
- // 如果最后一次因为 !retryAble 而没有进行重试
- // ref.attempt.errors 中将缺少最后的这个错误
- // ref.attempt.errors 中包含最后一次错误信息
- if (!retryAble) {
- ref.attempt.errors.push(info);
- }
- }
- }
- return readyToRetry;
- };
- operation.attempt(async () => {
- try {
- const result = await fn(operation.attempts());
- if (!isReadyToRetry(null, result, operation)) {
- resolve(result);
- }
- }
- catch (e) {
- try {
- if (!isReadyToRetry(e, null, operation)) {
- reject(e);
- }
- }
- catch (e) {
- reject(e);
- }
- }
- }, retryOptions.timeoutOps);
- });
- }
- exports.withRetry = withRetry;
|