jQuery JavaScript clearTimeout 不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17368453/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 18:54:44  来源:igfitidea点击:

JavaScript clearTimeout not working

javascriptjqueryajax

提问by user982119

(I've looked at all similar questions/answers but none of them solve my problem.)

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

The code:

编码:

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);
    }
}

The AJAX function simply calls showLoader(true)before calling the server, and then showLoader(false)after a result. I still sometimes see the text change from "Loading..." to "Still loading..." long before 15 seconds, so it's as if a timer thread is still running. Is there something wrong with the code above? Or could the problem be with other code..

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

edit:I must add that showLoader(true)can be called again (and again) before a response from the server

编辑:我必须添加showLoader(true)可以在来自服务器的响应之前再次(再次)调用

回答by DiverseAndRemote.com

You should add a check to see if there is already a timeoutHandlebefore creating a new one.

timeoutHandle在创建新的之前,您应该添加一个检查以查看是否已经存在。

try this:

尝试这个:

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

and then in the else case set timeoutHandleto null after you clear it like so:

然后在 else 情况下设置timeoutHandle为 null 后像这样清除它:

clearTimeout(timeoutHandle);
timeoutHandle = null;

This will eliminate the chance of you creating concurrent timeouts if showLoader(true)function is called more than once.

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

回答by Halcyon

What might be happening is that you're placing multiple calls to showLoadersince this is a global function you can access it from anywhere, you typically don't want that.

可能发生的情况是您要多次调用,showLoader因为这是一个全局函数,您可以从任何地方访问它,您通常不希望这样。

I would consider changing it to a monadimplementation:

我会考虑将其更改为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;
        }
    };
}

Usage:

用法:

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"));

Now you have a loaderobject that knows about it's own state.

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

回答by Mike Walston

In your post you mention that showloader can be called multiple times before the first return. This is your problem. You are overwriting an already existing timeoutHandle with a new one without destroying the already existing handle. You should check if the timeoutHandle is set or not set before you create a new one.

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

回答by Pinal

You don't call clearTimeout(timeoutHandle)then starting new request, if timeoutHandle exist

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