在setTimeout回调被调用后再用同样的ID调用clearTimeout会怎么样?
发布于 7 天前 作者 jinkankakushoujo 876 次浏览 来自 问答

当setTimeout回调被调用后,该ID是否会立刻被自动释放,还是在回调返回之后才会自动释放? 如果是立刻被自动释放,那么在回调里用同样的ID调用clearTimeout似乎可能出问题。

12 回复

setTimeout 返回的 ID 只是为了方便提前取消,一旦到了时间执行了回调(注意js是单线程的),立即就没什么用了。 打个比方,就像定时炸弹的定时器,爆炸之前可以取消掉,开始爆了、爆了之后还有什么用呢?

@myy 就是怕有另外一个定时器也返回相同的ID,然后错把别的定时器给取消了。

@myy 我给你举个例子,比如在setTimeout 的回调函数中又调用了多个setTimeout,如果ID在调用回调的时候就自动被释放了,那么在回调函数中调用多个setTimeout不就有可能又分配到相同的ID,然后在对之前已经触发了的ID调用clearTimeout可能就会正好和新分配的ID重复,从而导致悲剧。

setTimeout()和setInterval()共用一个编号池, 意味着不可能会产生相同的ID

https://developer.mozilla.org/zh-CN/docs/Web/API/Window/setTimeout

@msforest 这是否也意味着,setTimeout返回的ID回调后不管调用多少次setTimeout都绝对不会和之前已经回调过的ID重复?如果是的话,那确实不用担心重复。

返回值timeoutID是一个正整数,表示定时器的编号。这个值可以传递给clearTimeout()来取消该定时。

需要注意的是setTimeout()和setInterval()共用一个编号池,技术上,clearTimeout()和 clearInterval() 可以互换。但是,为了避免混淆,不要混用取消定时函数。

在同一个对象上(一个window或者worker),setTimeout()或者setInterval()返回的定时器编号不会重复。但是不同的对象使用独立的编号池。

你既然知道它有可能会出问题,那为什么不去避免它出问题,即使它在这个环境下不出问题,那在别的js引擎下也不会有问题吗?

@zengming00 凡事都有个约定,就算是其他的引擎,也应该要遵循w3的规范来吧,不然怎么解析现有的js脚本

@jinkankakushoujo 我理解的池子,类似于一个源头,源源不断地产生新的东西,两者之间永远不会有重复的,前提是同一个池子

@msforest 这个不一定的,arr.length mdn上写的是不可能为负数的,但csv模块的源码中竟然假设它有可能为负数

@zengming00 那估计是别有用意吧

timeID应该是个32位的整数,理论上是会重复的,但应该极难遇到,可以当做是不会冲突。 事实上,就算从0开始不回头的+1顺延,也根本用不完,你根本就创建不了那么多定时器嘛。 操作系统的 ProcessID, ThreadID 之类的也一样啊。。

回到顶部