retry.js

import sleep from './sleep';
import tryit from './tryit';
/**
 * 异步函数错误重试。
 *
 * @alias module:Util.retry
 * @since 1.14.0
 * @param {Function} fn 异步函数。
 * @param {Object} [options] 配置项。
 * @param {number} [options.times=3] 异步函数发生错误,最多重试次数。默认 `3`。
 * @param {number} [options.delay] 重试延迟时长,单位毫秒。
 * @param {Function} [options.backoff] 类似于延迟,便于实现指数后退。
 * @param {Function} [options.exit] 主动退出断言。
 * @returns 如果异步函数 `resolve` ,返回异步函数结果,否则抛出错误。
 * @example
 * let count = 1;
 * const fn = () => ++count < 3 ? Promise.reject('error') : Promise.resolve('success');
 * const result = await retry(fn); // 'success';
 *
 * try{
 *   // 延迟使用指数后退。
 *   await retry(verifySecret, { times: 100, backoff(count){ return count*count } })
 * }catch(err){
 *   console.log(err);
 * }
 */
async function retry(fn, options
// @ts-ignore
) {
    const { times = 3, delay, backoff, exit } = options || {};
    for (let i = 1; i <= times; i++) {
        const [err, result] = await tryit(fn)();
        if (!err)
            return result;
        if ((exit && exit(err, i)) || i === times)
            throw err;
        if (delay)
            await sleep(delay);
        if (backoff)
            await sleep(backoff(i));
    }
}
export default retry;