JavaScript请求重试需每次发送前用performance.now()记录开始时间,结束后立即计算并上报真实耗时,字段含url、retryCount、durationMs、status等,避免包含退避等待时间,且上报须非阻塞。

在 JavaScript 请求重试逻辑中,记录每次重试的耗时到日志系统,关键是在每次发起请求前打一个时间戳,请求结束(无论成功或失败)后计算差值,并将该耗时连同重试次数、URL、状态等上下文一并上报。
在每次重试前记录开始时间
不要只在最外层记一次开始时间,而应在每次实际发送请求前单独记录。这样能准确反映每一次重试的真实耗时(含网络延迟、服务响应等),避免把等待重试间隔的时间也计入。
- 使用 Date.now() 或 performance.now()(更精确,推荐用于性能敏感场景)获取毫秒级时间戳
- 将时间戳作为上下文传入当前重试尝试的执行作用域中
- 示例:在 fetch 封装函数中,每次调用前生成
startTime = performance.now()
请求结束后立即计算并上报耗时
在 then 或 catch 中(或 async/await 的 try/catch 块末尾),用当前时间减去本次的 startTime,得到真实请求耗时,并构造日志对象。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 日志字段建议包含:
url、method、retryCount(从 0 或 1 开始需统一)、durationMs、status(如 'success' / 'failed' / 'timeout')、httpStatus(如果可获取) - 即使请求失败(如网络错误、500),也要记录耗时——这对排查下游不稳定很有价值
- 避免在 finally 中统一上报,因为可能无法区分是哪一次重试的结束
与日志系统对接的常见方式
根据你使用的日志方案,选择轻量、非阻塞的上报方式:
立即学习“Java免费学习笔记(深入)”;
- 前端常用:调用
console.log(开发期)、logService.info()(自研 SDK)、或通过fetch发送到日志收集接口(注意节流和采样) - 确保日志上报不阻塞主流程,建议用
void fetch(...)或logService.report(...).catch(() => {}) - 可加简单上下文标识,如
logId: 'req-' + Math.random().toString(36).substr(2, 8),便于前后端联查
完整轻量示例(基于 fetch + async/await)
(省略错误处理细节,聚焦耗时记录逻辑)
async function requestWithRetry(url, options = {}, maxRetries = 3) {
for (let i = 0; i <= maxRetries; i++) {
const startTime = performance.now();
try {
const res = await fetch(url, options);
const duration = performance.now() - startTime;
logRetryEvent({ url, retryCount: i, duration, status: 'success', httpStatus: res.status });
return res;
} catch (err) {
const duration = performance.now() - startTime;
const status = err.name === 'AbortError' ? 'timeout' : 'failed';
logRetryEvent({ url, retryCount: i, duration, status, error: err.message });
if (i === maxRetries) throw err;
await new Promise(r => setTimeout(r, Math.min(1000 * 2 ** i, 5000))); // 指数退避
}
}
}
<p>function logRetryEvent({ url, retryCount, duration, status, httpStatus, error }) {
const log = {
level: 'info',
message: <code>HTTP ${status} on retry #${retryCount}</code>,
url,
retryCount,
duration: Math.round(duration),
httpStatus,
error,
timestamp: new Date().toISOString()
};
// 调用你的日志 SDK,例如:
// logger.info(log);
// 或:navigator.sendBeacon('/log', JSON.stringify(log));
}

















