返回

JS 定时器遇浏览器调度:柳暗花明,皆因改写

前端

前言

计时器被广泛应用于网络开发之中,成为获取时间、延时执行乃至实现动画效果等场景的可靠工具。JavaScript 定时器作为一种非阻塞式的定时机制,通过定时器对象实现延时或定时任务的执行。
本文将着眼于 JS 定时器与浏览器调度的关系,剖析浏览器置于后台或最小化时定时器任务可能无法执行的潜在原因,并给出可行的解决方案,以期帮助开发人员更好地理解和运用 JavaScript 定时器。

JavaScript 定时器运作机制

JS 定时器是通过 Window 对象下的 setTimeout() 和 setInterval() 两个方法实现的,这两个方法的参数都是一个函数,其功能是在指定的时间间隔后执行该函数。setTimeout() 用于设置一次性定时器,指定的时间间隔后只执行一次函数;setInterval() 则用于设置循环定时器,每隔指定的时间间隔执行一次函数,直到 clearInterval() 被调用来清除它。

浏览器调度

浏览器调度是浏览器运行时的一种机制,用于管理和协调执行各种任务,包括 JavaScript 代码、网络请求、DOM 更新、页面渲染等。浏览器调度器按照一定的优先级,轮流执行这些任务。当一个任务需要执行时,调度器会将其加入任务队列,等待执行。

调度机制与定时器执行

当浏览器置于后台或最小化时,浏览器的调度机制会发生变化。此时,浏览器会降低对 JavaScript 代码的调度优先级,以节省系统资源。这意味着,如果在浏览器后台或最小化时设置一个 JavaScript 定时器,则该定时器任务可能会被延迟执行,甚至可能根本无法执行。

解决方案

  • 清除并重置定时器:
    在浏览器置于后台或最小化时,可以清除现有的定时器并重新创建它。例如,对于 setTimeout(),可以先调用 clearTimeout() 来清除现有定时器,然后在浏览器重新获得焦点时,重新调用 setTimeout() 来创建新的定时器。
  • 使用 requestAnimationFrame():
    requestAnimationFrame() 是浏览器提供的另一个定时器 API,与传统的 JavaScript 定时器不同,它与浏览器的渲染引擎紧密相关。当浏览器执行 requestAnimationFrame() 时,它会将要执行的函数放入渲染队列中,等待浏览器准备渲染时再执行。这意味着,即使浏览器处于后台或最小化,只要浏览器仍在继续渲染页面,requestAnimationFrame() 就会继续执行。

结语

JS 定时器与浏览器调度之间有着密切的关系。在浏览器置于后台或最小化时,由于调度机制的变化,定时器任务可能会无法执行。为了解决这个问题,我们可以使用 clearTimeout() 和 setTimeout() 函数清除并重置定时器,或者使用 requestAnimationFrame() 来确保任务的执行。