JavaScript clearTimeout不起作用

时间:2013-06-28 15:34:45

标签: javascript jquery ajax

(我看过所有类似的问题/答案,但没有一个能解决我的问题。)

代码:

var timeoutHandle;

function showLoader(show) {
    if (show) {
        $('.loader').html('Loading...');
        $('.loader').show();

        timeoutHandle = setTimeout(function () {
            if ($('.loader').is(':visible')) {
                $('.loader').html('Still loading...');
            }
        }, 15000);
    }
    else {
        $('.loader').hide();
        clearTimeout(timeoutHandle);
    }
}

AJAX函数在调用服务器之前只调用showLoader(true),然后在结果之后调用showLoader(false)。我有时会在15秒之前看到文本从“正在加载...”更改为“仍然加载...”,因此就好像计时器线程仍在运行一样。上面的代码有什么问题吗?或者问题可能与其他代码有关..

编辑:我必须补充一点,showLoader(true)可以在来自服务器的响应之前再次(再次)调用

4 个答案:

答案 0 :(得分:19)

在创建新帐号之前,您应该先添加一项检查,看看是否已有timeoutHandle

试试这个:

if(timeoutHandle){
    clearTimeout(timeoutHandle);
    timeoutHandle = null;
}
timeoutHandle = setTimeout(function () {
    if ($('.loader').is(':visible')) {
        $('.loader').html('Still loading...');
    }
}, 15000);

然后在else情况下将timeoutHandle设置为null,然后清除它:

clearTimeout(timeoutHandle);
timeoutHandle = null;

如果多次调用showLoader(true)函数,这将消除您创建并发超时的可能性。

答案 1 :(得分:3)

可能发生的情况是,您要拨打showLoader多个电话,因为这是一个全局功能,您可以从任何地方访问它,您通常不希望这样。

我会考虑将其更改为 monad 实现:

function create_loader(elem) {
    var handle = null;

    function show() {
        elem.html('Loading...');
        elem.show();

        if (handle !== null) {
            clearTimeout(handle); // clear the previous one
        }
        handle = setTimeout(function () {
            elem.html('Still loading...');
        }, 15000);
    }

    return {
        show: show,
        clear: function () {
            elem.hide();
            clearTimeout(handle);
            handle = null;
        }
    };
}

用法:

var loader = create_loader($(".loader"));
loader.clear();
loader.show();
loader.show(); // each new call to show will reset the 15s timer
loader.show();
loader.show();
loader.clear();
// and you can make another one that operates independently of other one
var another_loader = create_loader($(".anotherLoader"));

现在你有一个loader对象知道它自己的状态。

答案 2 :(得分:1)

在你的帖子中你提到showloader可以在第一次返回之前多次调用。这是你的问题。您正在使用新的timeoutHandle覆盖已存在的timeoutHandle,而不会破坏现有的句柄。在创建新的timeoutHandle之前,应检查是否设置了timeoutHandle。

答案 3 :(得分:0)

如果存在timeoutHandle,则不要调用 clearTimeout(timeoutHandle)然后启动新请求