用户切到别的标签页查邮箱,回来看到按钮上写着 40 秒后重发,等了两分钟还是这个数字,刷新一下才变成可以重发。日志里能对上时间点,这种反而好排。

倒计时用 setInterval 每秒减一,后台标签页的定时器被浏览器节流到一分钟一次,页面上的数字和真实时间脱节。计时基准如果用累减,误差会一直累积。这一点先确认清楚,后面就不用反复试。

const until = Date.now() + 60 * 1000;
const tick = () => {
  const left = Math.max(0, Math.ceil((until - Date.now()) / 1000));
  btn.textContent = left ? left + ' 秒后重发' : '重新发送';
};
setInterval(tick, 1000);

「倒计时后台节流」确认了原因之后,改动尽量只碰那一处,顺手改的东西后面最容易出问题。能分两步做的操作就别合成一步,中间看一眼返回值,出问题好判断。

处理上按这个顺序:改成记录截止时间戳,每次渲染用当前时间减,别在内存里做减法;页面重新可见时立刻重算一次,把显示对齐;重发按钮的可用状态以服务端返回的下次可发时间为准;切走两分钟再回来,看按钮是否已经恢复。

结果对不对很好判断,切走再回来,倒计时数字直接跳到正确值,按钮按真实时间恢复。

作者 9823189