0ms setTimeout 之后是否需要clearTimeout?

Is clearTimeout necessary after setTimeout with 0ms?

正如我已经了解到的(此处:https://www.youtube.com/watch?v=8aGhZQkoFbQ),在某些情况下调用具有 0 毫秒延迟的 setTimeout(由于事件循环)可能很有用。

现在通常每当我使用 setTimeout 时,我也会注意在适当的位置调用 clearTimeout 以确保没有任何东西留在某处并在我不希望它成为的地方执行已执行。

所以我的问题是:是否有必要(有意义)在 setTimeout 之后用 0 毫秒调用 clearTimeout?传递的函数会立即附加到回调队列中,因此我假设 clearTimeout 不会(也不能)做任何事情。或者 clearTimeout 甚至可以从回调队列中删除传递的函数(所以在超时到期后但函数执行之前)?

第二个问题:即使它什么都不做,在那些情况下是否总是'best practice'调用clearTimeout

Is it necessary (does it make sense) to call clearTimeout after a setTimeout with 0ms?

没有。这是毫无意义的。

The passed function is immediately appended to the callback queue so I would assume clearTimeout does not (and cannot) do anything.

如果您在最初设置超时的同一函数中调用它,它可以做一些事情,但那将是愚蠢的,如果您这样做,您不应该首先调用 setTimeout .

Even if it does not do anything, is it anyway 'best practice' to call clearTimeout always in those cases?

没有。没意义。

I also take care to call clearTimeout at the appropriate spot to make sure nothing remains somewhere and gets executed at a point where I do not want it to be executed.

这里的关键词是"the appropriate spot"。没有通常适合调用 clearTimeout 的位置。

clearTimeout 将删除该功能。在你的 Chrome 控制台试试这个:

var timer = setTimeout(function() { console.log('hello'); }, 0);
clearTimeout(timer);

不,如果您打算执行超时,则不需要使用 clearTimeout

clearTimeout方法仅用于停止执行超时。您 可以 停止超时,即使它的时间为 0 毫秒,因为它不会执行,直到您退出您的函数并且 return 将控件交给浏览器。

Is it necessary (does it make sense) to call clearTimeout after a setTimeout with 0ms?

必要的if 目标是防止运行ning 的异步定时器回调。执行顺序完全可以根据 何时 回调被调用来讨论。

首先,0 毫秒作为延迟的值意味着 'run the callback as soon as possible'(来自未来的异步上下文),但是

  1. 不会改变how setTimeout works;和

  2. 0 is not the actual value used 无论如何。

The passed function is immediately appended to the callback queue so I would assume clearTimeout does not (and cannot) do anything.

这是不正确的。传递的函数是不是"immediately appended to the callback queue"。相反,超时到期并且计时器仍然有效时,将调用回调函数。可能还有其他异步回调 - 来自计时器或其他方式 - 可能是 运行 之前。

此外,所有剩余的同步代码都保证在计时器回调发生之前 运行:清除此上下文中的超时会阻止调用计时器回调,无关紧要 在同步代码中花费的时间。

Even if it does not do anything, is it anyway 'best practice' to call clearTimeout always in those cases?

调用 clearTimeout 将

  1. 如果在回调之前被清除(因为它删除了计时器),则阻止回调执行,或者;

  2. 如果回调已经发生则什么也不做(因为计时器不再有效)

因此 code/algorithm 的正常运行需要清除计时器;或者这是一个无用的操作。创建一个定时器只是为了立即取消它可能毫无意义,但这是关于代码结构的题外话..

I also take care to call clearTimeout at the appropriate spot to make sure nothing remains somewhere and gets executed at a point where I do not want it to be executed.

如上,无需手动清除不再活动的计时器;并且在调用定时器回调之前取消定时器将删除定时器,从而阻止定时器回调的执行。

When/where/if是否取消定时器取决于整体设计。


在执行代码中取消超时会阻止回调 运行ning:"A" 或 "B" 回调都不会 运行.

a = setTimeout(function () { console.log("A"); }, 0);
clearTimeout(a);

b = setTimeout(function () { console.log("B"); }, 0);
s = Date.now()
while (Date.now() - s < 100) { /* waste 100ms of CPU */ }
clearTimeout(b);

取消异步事件中的超时,运行s 首先阻止来自 运行ning 的回调:"B" 回调永远不会 运行:.

a = setTimeout(function () { console.log("A"); clearTimeout(b); }, 0);
b = setTimeout(function () { console.log("B"); }, 0);

虽然使用了辅助计时器(因为顺序得到了很好的保证),但其他异步事件(按钮点击、网络工作者、AJAX 等)也有可能在“ 0 毫秒”超时。

回调后(从任何上下文)调用的 clearTimeout 是无用的:

a = setTimeout(function () { console.log("A"); clearTimeout(a); }, 0);

a = setTimeout(function () { console.log("A"); }, 0);
b = setTimeout(function () { console.log("B"); clearTimeout(a); }, 0);

const timeout = setTimeout(() => {
    console.log('sdfsdf');
    clearTimeout(timeout);
}, 0);