重新触发调用时强制重置Promise 实现可重置的异步通知弹窗功能
异步通知浮层重置功能修复方案
核心问题点
你的代码出现重置失效、时长累加的核心原因有2个:
- 没有存储
clearAlert内部setTimeout的引用,无法主动清除正在等待执行的关闭定时器 - 多次触发
callAlert时会生成多条独立的异步执行链,多个定时器、Promise状态互相干扰
修复后完整代码
let alertActive = false; const ALERT_DISPLAY_DURATION = 1500; // 统一配置浮层展示时长 let clearAlertTimer = null; let showAlertPromise = null; function newAlert(){ // 如果已经在执行展示逻辑,直接返回已有Promise,避免重复执行 if (showAlertPromise) return showAlertPromise; showAlertPromise = new Promise((resolve,reject)=>{ setTimeout(()=>{ alert_pop.classList.remove("alert_pop"); alertActive = true; showAlertPromise = null; resolve(); } , 100); }); return showAlertPromise; } function resetAlertCountdown() { // 先清除上一个未执行的关闭定时器 if (clearAlertTimer) { clearTimeout(clearAlertTimer); } // 重置新的关闭定时器 clearAlertTimer = setTimeout(()=>{ alert_pop.classList.add("alert_pop"); alert_string.innerHTML = ""; alertActive = false; clearAlertTimer = null; } , ALERT_DISPLAY_DURATION); } async function callAlert(){ // 如果浮层已经在展示,直接重置倒计时即可 if (alertActive) { resetAlertCountdown(); return; } // 浮层未展示,先执行展示逻辑 await newAlert(); // 启动关闭倒计时 resetAlertCountdown(); }
修改说明
- 新增
clearAlertTimer变量存储关闭定时器的引用,每次重置倒计时前先清除上一个定时器,彻底解决重置失效问题 - 新增
showAlertPromise避免多次点击重复执行浮层展示逻辑,防止状态冲突 - 拆分出独立的
resetAlertCountdown方法处理倒计时重置逻辑,无需每次触发都走完整的异步Promise链,避免时长累加问题 - 用常量统一管理浮层展示时长,方便后续统一修改配置
内容的提问来源于stack exchange,提问作者Kris West
相关产品推荐
相关产品推荐

