21

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

编码:

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

4 回答 4

30

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)如果函数被多次调用,这将消除您创建并发超时的机会。

于 2013-06-28T15:37:46.140 回答
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知道它自己状态的对象。

于 2013-06-28T15:38:03.993 回答
1

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

于 2013-06-28T15:42:06.653 回答
0

如果 timeoutHandle 存在,您不要调用clearTimeout(timeoutHandle)然后开始新请求

于 2013-06-28T15:44:08.817 回答