setTimeout和setInterval的延迟时间只是一个参考值

2020-09-22 10:44:19 小象Web开发

setTimeout 和 setInterval 方法允许我们在指定的毫秒数之后执行一个函数。对于 setInterval 方法,它会重复执行这个函数。

很多人都没有意识到一个问题:这两个方法在运行方法之前会等待多久?答案是你在调用这两个方法时指定的是最小延迟时间,并非精准的时间。

它只是一个参考值。

为什么 setTimeout 和 setInterval 不能精确地在延迟结束后运行?

有几个原因可以解释为什么延迟比指定的时间要长。如下是几个最常见的原因:

根据 HTML5 规范,定时器的调用可以嵌套;发生5次嵌套之后,延迟时间被强制设定为至少4毫秒。

例如如下代码:

虽然我们为 setTimeout 和 setInterval 设置的延迟为 0 毫秒,实际执行时开始的延迟为1毫秒或者2毫秒,但是后面开始被限制为至少4毫秒。

现代浏览器对于规范的实现略有差异。在 Chrome 和 Firefox 中,从第5次连续调用开始会被限制;Safari 是从第6次调用开始;Edge 是从第3次开始。

要在现代浏览器中实现0毫秒延迟的定时器,可以借助 window.postMessage()。

为了减少性能负担,节省电量,非活跃标签页中的定时器被限制为一秒内最多执行一次。

Firefox 从版本 5 开始支持这个行为,Chrome 是从版本 11 开始实现的。

我们都知道 JavaScript 是单线程运行的,许多操作是同步的。页面中的定时器必须等到线程空闲时才会调用。例如:

在控制台的输出如下:

这是因为虽然 setTimeout 是先调用的,而且设置了0毫秒的延迟。它会被放入队列,等待下次有机会时才运行,而不是立即执行。当前执行中的代码必须在队列处理之前先执行,所以输出的结果可能不是你期望的那样。

如果需要执行的同步操作特别耗时,你在定时器中的函数可能要等待很久才会执行。

包括 IE,Chrome,Safari 和 Firefox 在内的浏览器使用的是32位有符号的整数来存储延迟时间。如果延迟值超过了 2,147,483,647毫秒(约为24.8天),会导致定时器立即执行。

也许你会有个疑问,谁会设置这么长时间的延迟呢?作为开发者,我们一般不会在程序中为定时器设置这么长时间的延迟,不过假如定时器中的延迟值来自用户的输入或者数据库中读取的值,则可能会出现此场景。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐

热门新闻