即使在达到超时成熟但没有获得执行机会之后,clearTimeout能否清除超时?

时间:2014-04-27 08:59:15

标签: javascript jquery callback onclick settimeout

假设我有一个运行客户端的功能渲染,可能需要100-1000毫秒 我有一个函数 fetch ,它发出服务器请求并成功,清除渲染超时,然后调用渲染时超时为100ms。 我有一个按钮, onclick ,再次清除渲染超时,然后调用渲染,超时为100ms。

当我尝试多次单击按钮时,我发现,如果已经发出了许多服务器请求,则只有第一个和最后一个响应导致呈现,正如预期的那样。 但这有保证吗?我能安全地依赖这个吗?

任何让我放心或告诉我有关陷阱的链接将不胜感激。 我已经通过了this 我知道无论是什么情况,如果发生任何asyc事件,它将排队并仅在第一次执行空闲时执行,但我对决定关于应该在哪里的内容感到困惑自浏览器完成以来的队列?

2 个答案:

答案 0 :(得分:0)

我找不到合适的资源,所以我尝试在浏览器中运行此脚本。

var doItLater = function () {
    alert("I did it!");
};

window.onload = function () {
    // set a timeout to execute immediately
    var timeout = window.setTimeout(doItLater, 0);

    for (var i = 0; i < 1000000000; i++) {
        // waste some time
    }
    // The timeout has definitely triggered by now.
    // doItLater is queued up to execute as soon as
    // this function returns.

    clearTimeout(timeout); // wait, I changed my mind!
};

// Does doItLater get called?

它有效! clearTimeout()可以防止调用doItLater(),即使它已经被放在队列中了。

另外,我建议您在的渲染功能中使用setTimeout()来防止页面无响应。对于函数阻塞事件循环,1000 ms太长了。 (例如,请参阅here

答案 1 :(得分:0)

我认为这是特定于JS-runtime实现的。例如,this SO问题表明,在IE上,即使在为clearTimeout()调用之后,也可以执行超时回调。

鉴于JS事件链的单线程特性,我建议你在调用clearTimeout()之前或之后设置一个控制标志,并在超时回调中检查该标志:

var isActive = true;
var timerId = setTimeout(function() {
    if (!isActive) return;
    // doStuff
}, someInterval);

...

function onSomeExternalEvent() {
    isActive = false;
    clearTimeout(timerId);
}