不要覆盖标准方法

需求:

页面不可见时,例如切换浏览器页签、最小化浏览器,暂停所有定时器;页面显示时,再启动定时器。


一个解决方案如下:

const uuid = (() => {
  let no = 0;
  return () => no++;
})();

const originSetInterval = window.setInterval;
const originClearInterval = window.clearInterval;

const timers = [];
const startTimers = () =>
  timers.forEach(t => {
    t.originIntervalId = originSetInterval(
      t.fn,
      t.ms
    );
  });
const stopTimers = () =>
  timers.forEach(t => {
    originClearInterval(t.originIntervalId);
  });

document.addEventListener(
  "visibilitychange",
  () =>
    document.visibilityState === "visible"
      ? startTimers()
      : stopTimers()
);

window.setInterval = (fn, ms) => {
  const originIntervalId =
    document.visibilityState === "visible"
      ? originSetInterval(fn, ms)
      : undefined;
  const id = uuid();
  timers.push({
    fn,
    ms,
    originIntervalId,
    id
  });
  return id;
};

window.clearInterval = id => {
  const t = timers.find(t => t.id === id);
  originClearInterval(t.originIntervalId);
  timers.splice(timers.indexOf(t), 1);
};

覆写 setIntervalclearInterval,不用改已有代码,所有定时器就都能自动启停。


但我不推荐在项目中这么做,宁愿麻烦点,写个 setSmartInterval ,全局替换 setInterval。原因有很多,例如:

  • 可能影响第三方库
  • 没法再用原生的 setInterval
  • 新人培训成本增加
  • ……

其中,我最看重的是:这么做导致 代码行为出人意料。当一个东西和经验认知不一样时,使用它要付出更多的思考。「Don't make me think」对于代码设计同样重要。

posted @   apolis  阅读(319)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示