выполнение функции блока во время setTimeout - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть функция, которую я вызываю, когда нажимаю кнопку.Моя цель - вывести «hello» на консоль через 5 секунд и, если я нажму кнопку в течение 5 секунд ожидания, ничего не будет.

Проблема в том, что, если я нажимаю кнопку, пока яЖду 5 секунд, в консоли я все равно получаю больше одного «привет».Что я делаю не так?

Вот код Javascript:

function foo(){
    var block = false;
    if(!block){
        block = true;
        myVar = setTimeout(checkAgain, 5000);
    }
    function checkAgain(){
        console.log("hello");
        block = false;
    }
}

И HTML:

<button id="button" onClick="foo();">Click me!</button>

Ответы [ 3 ]

0 голосов
/ 27 ноября 2018

это потому, что вы определили переменную 'block' в области действия функции 'foo', и она вызывается снова каждый раз, когда вы вызываете функцию.правильная реализация:

var block = false;

function foo(){
  if (!block) {
    block = true;
    myVar = setTimeout(checkAgain, 5000);
  }

  function checkAgain() {
    console.log("hello");
    block = false;
  }
}
0 голосов
/ 27 ноября 2018

Вам не нужно вручную обрабатывать «блок», вы можете просто отменить вызов с помощью clearTimeout.Это кажется более естественным для меня - когда вы нажимаете один раз, когда говорите «вызовите эту функцию через 5 секунд», а когда вы нажимаете ее снова, вы говорите «не вызывайте ее».

var timeout = null;
var button = document.querySelector("#btn");

button.onclick = function()
{
  if (timeout) 
  {
    clearTimeout(timeout);
    timeout = null;
  }
  else 
  {
    timeout = setTimeout(function() { 
      timeout = null;
      run();
    }, 1000); // should be 5000, just for test
  }
};

function run()
{  
  console.log("Hello world");
}
<input type="button" id="btn" value="Click me">
0 голосов
/ 27 ноября 2018

Вы ничего не делаете, чтобы заблокировать последующие звонки.block - это локальная переменная внутри foo, поэтому для каждого вызова foo.

по-разному. Вместо этого вы должны иметь block снаружи foo:

var myVar;
var block = false;
function foo(){
    if(!block){
        block = true;
        myVar = setTimeout(checkAgain, 5000);
    }
    function checkAgain(){
        console.log("hello");
        block = false;
    }
}
document.getElementById("btn").addEventListener("click", foo);
<input type="button" id="btn" value="Click me">

Это также означает, что checkAgain не нужно создавать заново для каждого вызова foo, так как ему не нужно ничего локального для foo больше:

var myVar;
var block = false;
function foo(){
    if(!block){
        block = true;
        myVar = setTimeout(checkAgain, 5000);
    }
}
function checkAgain(){
    console.log("hello");
    block = false;
}
document.getElementById("btn").addEventListener("click", foo);
<input type="button" id="btn" value="Click me">

(Я предполагаю, что все это находится в функции или модуле определения объема, поэтому это не глобальные значения.)

Тем не менее, кнопка останется активной, создавая впечатление, что пользователь может нажать на нее.Вместо этого вы можете подумать о том, чтобы foo мог отключить и снова включить кнопку.

...