欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

不要覆盖标准方法

程序员文章站 2022-06-19 10:36:50
页面不可见时,例如切换浏览器页签、最小化浏览器,暂停所有定时器;页面显示时,再启动定时器。 ......

需求:

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


一个解决方案如下:

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
  • 新人培训成本增加
  • ……

其中,我最看重的是:这么做导致 代码行为出人意料。当一个东西和经验认知不一样时,使用它要付出更多的思考。每次用 setinterval,都会想一下它和原生的区别。看起来是小事,却会打断你的思路。“don't make me think”对于代码设计同样重要。