防止 JavaScript 函数运行两次 (setTimeout)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23119282/
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-10-28 00:22:26  来源:igfitidea点击:

Prevent JavaScript function from running twice (setTimeout)

javascriptfunctionsettimeoutexecution

提问by user3320550

I have this function that runs for several seconds with the use of setTimeout. This function is ran when a button is clicked.

我有这个功能,使用setTimeout. 单击按钮时会运行此函数。

function complete() {
    var div = document.getElementById('log');
    setTimeout(function(){ div.innerHTML = div.innerHTML + intro[Math.floor(Math.random() * intro.length)] + "<br>"; }, 500);
    setTimeout(function(){ div.innerHTML = div.innerHTML + second[Math.floor(Math.random() * second.length)] + "<br>"; }, 2560);
    setTimeout(function(){ div.innerHTML = div.innerHTML + third[Math.floor(Math.random() * third.length)] + "<br>"; }, 4860);
    setTimeout(function(){ div.innerHTML = div.innerHTML + fourth[Math.floor(Math.random() * fourth.length)] + "<br>"; }, 7860);
    setTimeout(function(){ div.innerHTML = div.innerHTML + fifth[Math.floor(Math.random() * fifth.length)] + "<br>"; }, 9640);
}

However, if the user clicks the button multiple times, this function begins to excute multiple times as well. I have tried to prevent this from occuring by using the code below, however, it is not working.

但是,如果用户多次单击该按钮,该功能也会开始执行多次。我试图通过使用下面的代码来防止这种情况发生,但是,它不起作用。

var running;
function complete() {
    if (running == true) { alert('error'); }
    running = true;
    var div = document.getElementById('log');
    setTimeout(function(){ div.innerHTML = div.innerHTML + intro[Math.floor(Math.random() * intro.length)] + "<br>"; }, 500);
    setTimeout(function(){ div.innerHTML = div.innerHTML + second[Math.floor(Math.random() * second.length)] + "<br>"; }, 2560);
    setTimeout(function(){ div.innerHTML = div.innerHTML + third[Math.floor(Math.random() * third.length)] + "<br>"; }, 4860);
    setTimeout(function(){ div.innerHTML = div.innerHTML + fourth[Math.floor(Math.random() * fourth.length)] + "<br>"; }, 7860);
    setTimeout(function(){ div.innerHTML = div.innerHTML + fifth[Math.floor(Math.random() * fifth.length)] + "<br>"; }, 9640);
    running = false;
}

What approach should I take, or how can I fix my code so it can accomplish what I am trying to do?

我应该采取什么方法,或者我如何修复我的代码以便它可以完成我想要做的事情?

回答by juvian

Your running = false;should be inside timeout function, as timeout will execute asyncronically, the running = false;will execute before your timeout ends

running = false;应该在超时函数内,因为超时将异步执行,running = false;将在超时结束之前执行

A simple example would be

一个简单的例子是

var running = false,
    div = document.getElementById('response'),
    limit = 5,
    current = 0;

$('#trigger').click(function () {
    if (running === true) {
        alert('Error: The cycle was running. Aborting.');
        running = false;
        return false;
    }
    running = true;
    var end = setInterval(function () {
        if (current >= limit || running == false) {
            running = false;
            clearInterval(end);
        }
        div.innerHTML += 'Hello World<br />';
        current++;
    }, 500);

});

JSFiddle Example

JSFiddle 示例

回答by Arthur Tsidkilov

for stop running timer you have to clear him

要停止运行计时器,您必须清除他

        var stopTimer;

        function someFunction() {
            stopTimer= setTimeout(function(){
                console.log("something done");
            }, 3000);
        }

        function stopFunction() {
            clearTimeout(stopTimer);
        }

回答by Teemu

Assuming you've used addEventListenerto attach the click event to the button, you could remove the listener while timeouts are in progress:

假设您曾经addEventListener将点击事件附加到按钮,您可以在超时期间删除侦听器:

function complete() {
    var div = document.getElementById('log'),
        button = this;
    this.removeEventListener('click', complete);
    setTimeout(function(){...});
                 :
    setTimeout(function(){...});
    // If you later want to make the button clickable again, just uncomment the line below:
    // setTimeout(function () {button.addEventListener('click', complete);}, 10000);
}

回答by levieraf

If you are using jquery it could be more easy.

如果您使用 jquery,它可能会更容易。

E.q:

function complete() {
    var div = document.getElementById('log');
    setTimeout(function(){ div.innerHTML = div.innerHTML + intro[Math.floor(Math.random() * intro.length)] + "<br>"; }, 500);
    setTimeout(function(){ div.innerHTML = div.innerHTML + second[Math.floor(Math.random() * second.length)] + "<br>"; }, 2560);
    setTimeout(function(){ div.innerHTML = div.innerHTML + third[Math.floor(Math.random() * third.length)] + "<br>"; }, 4860);
    setTimeout(function(){ div.innerHTML = div.innerHTML + fourth[Math.floor(Math.random() * fourth.length)] + "<br>"; }, 7860);
    setTimeout(function(){ div.innerHTML = div.innerHTML + fifth[Math.floor(Math.random() * fifth.length)] + "<br>"; }, 9640);

    $( "input[type='button']" ).unbind( "click", complete );
}


$( "input[type='button']" ).bind( "click", complete );

I did some example for you: http://jsfiddle.net/ZA5Ga/

我为你做了一些例子:http: //jsfiddle.net/ZA5Ga/

good luck!

祝你好运!