在再次执行之前等待执行完成

时间:2015-10-22 02:17:35

标签: javascript jquery

我想阻止我的点击处理程序多次执行,但是它没有按预期工作。我的方法是否朝着正确的方向发展?我希望当用户单击按钮一次时执行此处理程序。当然,这个处理程序可以再次执行(执行完成后)。



var init = false,
    i = 1;

$('button').on('click', function() {
  if (init) {
    return;
  }

  init = true;

  (function() {
    // this for loop is for example purposes, just to have something running
    for (var i = 0; i < 5000; i++) {
      $('.text').append(i)
    }
    init = false;
  }());

  $('.counter').html(i);
  i++
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">Button</button>
<div class="text"></div>
<div class="counter"></div>
&#13;
&#13;
&#13;

3 个答案:

答案 0 :(得分:1)

尝试使用buttondisabledtrueinit开头设置.hide()属性.delay().show(),将disabled属性设置为false

&#13;
&#13;
var count = 1,
  max = 5000,
  init = function() {
    $(this).prop("disabled", true)
    .off("click.count");
    $(".counter").html(count);
    count++;
    $(this).hide(0, function() {
      for (var i = 0; i < max; i++) {
        $(".text").append(i);
      }
    }).delay(max / 2).show(function() {
      $(this).prop("disabled", false)
      .on("click.count", init)
    })
  };

$("button").on("click.count", init);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<button id="button">Button</button>
<div class="text"></div>
<div class="counter"></div>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

这里尝试这个解决方案。

首先我们将点击处理程序注册到按钮:

$('button').on('click', runThis );

这里是runThis()处理函数:

function runThis() {
  // register off click handler on button
  $('button').off('click');    
  // loop over i
  for (var i = 0; i < 2000; i++) {
    $('.text').append('<br/>' + i);        
  }
  // if execution finish
  if (i == 2000) {
    // register back handler
    addBack();
  }
}

我们在这里按下按钮上的点击处理程序:

function addBack() {
   $('button').on('click', runThis );
}

答案 2 :(得分:0)

在确定UI被阻止之后,我研究了将循环“分块”成更小循环的解决方案,允许UI被解除阻塞并执行其他功能。

Chunked for loop

function loop(arr, fn, before, callback) {
    let index = 0,
        step = 50,
        stepTotal = step;

    before();

    (function chunk() {
        while(index < arr.length && index < stepTotal) {
            fn(arr[index], index);
            index++;
        }

        if (index < arr.length) {
            stepTotal+=step;
            setTimeout(chunk, 0);
        } else {
            callback();
        }
    })()
}