pacote-install
Version:
A tool to download npm packages from specific registries
46 lines (45 loc) • 1.68 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.withRetry = withRetry;
const logger_1 = __importDefault(require("./logger"));
/**
* 带重试的异步操作执行器
* @param fn 要执行的异步函数
* @param options 重试选项
* @returns 异步结果
*/
async function withRetry(fn, options = {}) {
const { retries = 3, factor = 2, minTimeout = 1000, maxTimeout = 30000, onRetry = (error, attempt) => {
logger_1.default.warn(`操作失败,第 ${attempt} 次重试,错误: ${error.message}`);
}, beforeFinish, } = options;
let lastError;
let attempt = 0;
while (attempt <= retries) {
try {
if (attempt > 0) {
// 计算延迟时间,使用指数退避策略
const delay = Math.min(Math.max(minTimeout * Math.pow(factor, attempt - 1), minTimeout), maxTimeout);
logger_1.default.debug(`等待 ${delay}ms 后重试...`);
await new Promise(resolve => setTimeout(resolve, delay));
}
const res = await fn();
if (beforeFinish) {
beforeFinish(res, attempt);
}
return res;
}
catch (error) {
lastError = error instanceof Error ? error : new Error(String(error));
attempt++;
if (attempt <= retries) {
onRetry(lastError, attempt);
}
}
}
// 所有重试都失败了
throw lastError;
}
exports.default = withRetry;