写一个方法实现promise失败后自动重试
/**
* 异步函数自动重试
* @param {Function} asyncFn 异步函数,必须返回一个 Promise
* @param {number} retries 重试次数,默认为 3
* @param {number} delay 重试间隔时间(毫秒),默认为 1000
* @param {Function} onRetry 可选,每次重试时的回调函数,接收当前重试次数作为参数
* @returns {Promise} 返回一个 Promise,成功时返回异步函数的结果,失败时返回最后一次错误
*/
function retryAsync(asyncFn, retries = 3, delay = 1000, onRetry) {
let retryCount = 0;
return new Promise((resolve, reject) => {
function attempt() {
asyncFn()
.then(resolve) // 成功则 resolve
.catch((error) => {
retryCount++;
if (retryCount < retries) {
if (onRetry) {
onRetry(retryCount, error); // 执行重试回调
}
setTimeout(() => {
console.warn(`Retrying ${asyncFn.name} (attempt ${retryCount + 1} of ${retries})...`);
attempt(); // 再次尝试
}, delay);
} else {
console.error(`Failed after ${retries} retries:`, error);
reject(error); // 超过重试次数,reject
}
});
}
attempt(); // 首次尝试
});
}
// 示例用法:
async function fetchData() {
// 模拟一个可能失败的异步操作
const success = Math.random() < 0.8; // 80% 的成功率
return new Promise((resolve, reject) => {
setTimeout(() => {
if (success) {
resolve("Data fetched successfully!");
} else {
reject(new Error("Network error"));
}
}, 500);
});
}
retryAsync(fetchData, 5, 2000, (retryCount, error) => {
console.log(`Retry attempt ${retryCount}: ${error.message}`);
})
.then((data) => {
console.log("Success:", data);
})
.catch((error) => {
console.error("Final Error:", error);
});
// 更简洁的async/await版本 (需要支持async/await的环境)
async function retryAsyncAwait(asyncFn, retries = 3, delay = 1000, onRetry) {
for (let i = 0; i < retries; i++) {
try {
return await asyncFn();
} catch (error) {
if (onRetry) {
onRetry(i + 1, error);
}
console.warn(`Retrying ${asyncFn.name} (attempt ${i + 1} of ${retries})...`);
if (i < retries - 1) { // 最后一次尝试失败后不再等待
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
throw new Error(`Failed after ${retries} retries`); // 抛出错误,让外部捕获
}
// async/await 版本使用示例
retryAsyncAwait(fetchData, 5, 2000, (retryCount, error) => {
console.log(`Retry attempt ${retryCount}: ${error.message}`);
})
.then((data) => {
console.log("Success (async/await):", data);
})
.catch((error) => {
console.error("Final Error (async/await):", error);
});
关键改进:
- 清晰的注释: 增加了详细的注释,解释每个参数和代码逻辑。
- 错误处理: 更完善的错误处理,包括在每次重试失败时打印错误信息,并在最终失败时 reject,方便外部捕获错误。
- 重试回调: 增加了
onRetry
回调函数,可以在每次重试时执行自定义逻辑,例如记录错误信息或更新 UI。 - 示例用法: 提供了更实际的示例,模拟一个可能失败的异步操作,并演示了如何使用
retryAsync
函数。 async/await
版本: 新增了使用async/await
的版本,代码更简洁易懂 (需要支持async/await
的环境)。- 控制台输出: 添加了控制台输出,方便调试
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· 地球OL攻略 —— 某应届生求职总结