不要覆盖标准方法
程序员文章站
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); };
覆写 setinterval
和 clearinterval
,不用改已有代码,所有定时器就都能自动启停。
但我不推荐在项目中这么做,宁愿麻烦点,写个 setsmartinterval
,全局替换 setinterval
。原因有很多,例如:
- 可能影响第三方库
- 没法再用原生的
setinterval
- 新人培训成本增加
- ……
其中,我最看重的是:这么做导致 代码行为出人意料。当一个东西和经验认知不一样时,使用它要付出更多的思考。每次用 setinterval
,都会想一下它和原生的区别。看起来是小事,却会打断你的思路。“don't make me think”对于代码设计同样重要。