正如我已经了解的那样(这里:https://www.youtube.com/watch?v=8aGhZQkoFbQ),在某些情况下,调用setTimeout延迟0ms(因为事件循环)会很有用。
现在通常每当我使用setTimeout
时,我也会注意在适当的位置调用clearTimeout
以确保没有任何东西留在某处并在我不希望它执行的位置执行。
所以我的问题是:在clearTimeout
之后用0ms调用setTimeout
是否有必要(有意义吗?)传递的函数会立即附加到回调队列中,因此我认为clearTimeout
不会(也不能)执行任何操作。或者clearTimeout
甚至可以从回调队列中删除传递的函数(因此在超时到期之后但在函数执行之前)?
第二个问题:即使它没有做任何事情,在这些情况下总是呼叫clearTimeout
是“最佳做法”吗?
答案 0 :(得分:11)
在具有0ms的setTimeout之后调用clearTimeout是否有必要(是否有意义)?
是必需的如果的目标是阻止异步计时器回调运行。执行顺序可以完全根据调用调用回调来讨论。
首先,作为延迟的0毫秒值意味着尽快运行回调' (来自未来的异步上下文),但:
它不更改how setTimeout works;以及
传递的函数会立即附加到回调队列中,因此我认为clearTimeout不会(也不能)执行任何操作。
这是不正确的。传递的函数 not "立即附加到回调队列"。相反,当超时到期和时,计时器仍处于活动状态,将调用回调函数。可能存在其他异步回调 - 来自计时器或其他 - 可以在之前运行。
此外,保证所有剩余的同步代码在定时器回调发生之前运行:在此上下文中清除超时可防止定时器回调被调用,无论同步代码所用的时间
即使它什么也不做,无论如何都是最好的做法'在那些情况下总是调用clearTimeout?
调用clearTimeout将
阻止回调执行,如果在回调之前清除(因为它删除了计时器),或者;
如果回调已经发生,则不执行任何操作(因为计时器不再处于活动状态)
因此,为了正确运行代码/算法,需要清除定时器;或者这是一个无用的操作。创建一个计时器只是为了立即取消它可能毫无意义,但这是对代码结构的偏离..
我还要注意在适当的位置调用clearTimeout以确保没有任何东西留在某处并在我不希望它被执行的位置执行。
如上所述,无需手动清除不再有效的计时器;并且在之前取消定时器以调用定时器回调将删除定时器,从而防止定时器回调执行。
何时/何时/如果取消计时器取决于整体设计。
取消执行代码中的超时会阻止回调运行:" 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);
在首先运行的异步事件中取消超时会阻止回调运行:&#34; B&#34;回调永远不会运行:。
a = setTimeout(function () { console.log("A"); clearTimeout(b); }, 0);
b = setTimeout(function () { console.log("B"); }, 0);
虽然使用了辅助计时器(因为订购得到了很好的保证),但在&#34; 0ms&#34之前也可能发生其他异步事件(按钮点击,网络工作者,AJAX等) ;超时。
在回调(从任何上下文)之后调用的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);
答案 1 :(得分:4)
clearTimeout
将删除该功能。请在Chrome控制台中试用:
var timer = setTimeout(function() { console.log('hello'); }, 0);
clearTimeout(timer);
答案 2 :(得分:1)
在具有0ms的setTimeout之后调用clearTimeout是否有必要(是否有意义)?
没有。这毫无意义。
传递的函数会立即附加到回调队列中,因此我认为clearTimeout不会(也不能)执行任何操作。
如果你在与第一个设置超时的函数相同的函数中调用它,它可以做一些事情,但这将是愚蠢的,如果你这样做,你应该首先不调用setTimeout。< / p>
即使它没有做任何事情,在这种情况下总是调用clearTimeout是“最佳做法”吗?
没有。这毫无意义。
我还要注意在适当的位置调用clearTimeout以确保没有任何东西留在某处并在我不希望它被执行的位置执行。
这里的关键词是“适当的地方”。调用clearTimeout没有通用的适当位置。
答案 3 :(得分:0)
不,如果您打算执行超时,则不需要使用clearTimeout
。
clearTimeout
方法仅用于停止执行超时。您可以停止超时,即使它的时间为0毫秒,因为它不会被执行,直到您退出函数并将控件返回到浏览器。