为NProgress添加5秒冷却:5秒内仅首个Promise触发进度条
实现NProgress进度条5秒内仅首次触发显示的逻辑
需求说明
当前每次调用nprogressWrapPromise都会触发进度条,需修改为:5秒内仅第一个触发的Promise显示进度条,后续触发的自动隐藏进度条。
修改后的完整代码
// 全局状态变量 let started = 0; let firstTriggerTime = null; const TIME_WINDOW = 5000; // 5秒时间窗口 // 进度条控制逻辑 function nprogressStartLoad() { if (started === 0) { window.NProgress.start(); } started++; return () => { started--; if (started <= 0) { started = 0; window.NProgress.done(); // 所有并发请求完成,重置时间戳 firstTriggerTime = null; } }; } // 带进度条的Promise包装函数 function nprogressWrapPromise(fn, hide = false) { const now = Date.now(); // 检查是否在5秒时间窗口内,且非首次触发 if (!hide && firstTriggerTime && (now - firstTriggerTime) < TIME_WINDOW) { hide = true; // 后续请求自动隐藏进度条 } if (hide) { return fn(); } // 首次触发,记录时间戳并设置5秒后重置 firstTriggerTime = now; setTimeout(() => { firstTriggerTime = null; }, TIME_WINDOW); const done = nprogressStartLoad(); // 使用finally确保无论成功失败都会调用done return fn().finally(() => { done(); }); } // 模拟异步任务的函数 function print(message) { return new Promise((resolve) => { setTimeout(() => { console.log(message); resolve(); }, 1000); }); }
调用示例
// 首次调用,触发进度条 nprogressWrapPromise(async () => await print("one")); // 5秒内的后续调用,自动隐藏进度条 nprogressWrapPromise(async () => await print("two")); nprogressWrapPromise(async () => await print("three")); // 5秒后调用,会重新触发进度条 setTimeout(() => { nprogressWrapPromise(async () => await print("four")); }, 5500);
核心逻辑说明
- 新增
firstTriggerTime记录首次触发的时间戳,TIME_WINDOW定义5秒的时间窗口 - 每次调用
nprogressWrapPromise时,先判断是否在时间窗口内:若是非首次触发,自动设置hide=true跳过进度条逻辑 - 首次触发时,设置定时器,5秒后自动重置时间戳,确保窗口过期后可重新触发进度条
- 使用
finally替代then,确保异步任务无论成功或失败都会正确结束进度条计数 - 当所有并发请求完成时,主动重置时间戳,避免窗口未过期但无请求时的状态残留
内容的提问来源于stack exchange,提问作者sanheart
相关产品推荐
相关产品推荐

