setTimeout为0毫秒后是否需要clearTimeout ?

Is clearTimeout necessary after setTimeout with 0ms?

本文关键字:clearTimeout 是否 0毫 setTimeout      更新时间:2023-09-26

正如我已经了解到的(在这里:https://www.youtube.com/watch?v=8aGhZQkoFbQ),在某些情况下调用setTimeout延迟0毫秒(因为事件循环)是有用的。

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

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

第二个问题:即使它不做任何事情,在这些情况下总是调用clearTimeout是"最佳实践"吗?

是否有必要(它是有意义的)在setTimeout与0ms后调用clearartimeout ?

必要的如果的目标是防止异步计时器回调运行。当调用回调时,执行顺序可以完全根据进行讨论。

首先,0毫秒作为延迟值意味着'尽快运行回调'(从未来的异步上下文中),但是:

  1. 改变setTimeout的工作方式;和

  2. 0是不是实际使用的值。

传递的函数会立即附加到回调队列中,所以我假设clearTimeout不会(也不能)做任何事情。

这是不正确的。传递的函数是而不是 "立即附加到回调队列中"。相反,当超时过期计时器仍处于活动状态时,将调用回调函数。可能会有其他异步回调——从计时器或其他方式——可以先运行。

同样,所有剩余的同步代码都保证在计时器回调发生之前运行:清除此上下文中的超时可以防止计时器回调被调用,无论同步代码占用的时间如何

即使它不做任何事情,无论如何'最佳实践'调用clearartimeout总是在这些情况下?

调用clearartimeout将要么

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

  2. 如果回调已经发生(因为计时器不再活动),则不做任何操作

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

我还注意在适当的位置调用clearartimeout,以确保没有任何东西在某处保留,并在我不希望执行的地方执行。

如上所述,不需要手动清除不再活跃的计时器;在之前取消计时器将删除计时器,从而阻止计时器回调执行。

何时/何地/是否取消定时器取决于整体设计。


取消执行代码中的超时将阻止回调运行:"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);

取消首先运行的异步事件的超时将阻止回调运行:"B"回调将永远不会运行:.

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

虽然使用了辅助计时器(因为顺序得到了很好的保证),但其他异步事件(按钮单击,web工作者,AJAX等)也可能在"0ms"超时之前发生。

在回调(从任何上下文中)之后调用的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);

clearTimeout将删除该功能。在Chrome控制台中试试:

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

是否有必要(它是有意义的)在setTimeout与0ms后调用clearartimeout ?

。这毫无意义。

传递的函数会立即附加到回调队列中,所以我假设clearTimeout不会(也不能)做任何事情。

如果你在第一次设置超时的函数中调用它,它可以做一些事情,但那将是愚蠢的,如果你要这样做,你不应该在第一次调用setTimeout。

即使它不做任何事情,无论如何'最佳实践'调用clearartimeout总是在这些情况下?

。这是没有意义的。

我还注意在适当的位置调用clearartimeout,以确保没有任何东西在某处保留,并在我不希望执行的地方执行。

这里的关键短语是"合适的位置"。没有适合调用clearartimeout的一般位置。

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

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

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