-1

我有以下情况:

$('button').on('click',function(){

    // Run AJAX commonds (May take some time);

});

因此,如果用户多次单击按钮,他可能会执行ajax很多请求。

解决这个问题的合乎逻辑的方法是使用

var finished = true;
$('button').on('click',function(){
    if(finished == true){
        finished = false;
        ....
        finished = true;
    }

但是为每个函数添加全局变量似乎很奇怪?我怎样才能解决这个问题?我调查.off()过,但这完全删除了该事件。one()只需执行一次。我不希望它执行多次。也许编写一个简单的插件来处理这个功能。它的重复。

4

4 回答 4

0

学习方法的简单.on()方法:http .off(): //jsbin.com/oguwux/1/edit

HTML:

<button id="btn">AJAX REQUEST</button>

jQuery:

function ajaxCall(){

  $(this).off('click');
  $(this).text('Processing...'); // test only

  setTimeout(function(){  // (example.) do your AJAX call instead
    // ON SUCCESS :
    $('#btn').text('AJAX REQUEST');
    $('#btn').on('click', ajaxCall);
  },2000);

}

$('#btn').on('click', ajaxCall);
于 2013-05-05T19:00:56.360 回答
0

您可以向元素添加数据或添加类以指示它仍在处理中。如果操作完成,则删除该数据/类名。

$('button').on('click',function(){

  var self = $(this);
  var processing = self.data('processing');

  if(!processing){ //if not processing

    self.data('processing',true); //flag as processing

    //do stuff
    $.ajax({...}).done(function(responseData){

      //when done, unflag
      self.data('processing',false);
    });
  }
});
于 2013-05-05T18:51:20.090 回答
0

一个选项可以是在请求处于活动状态时禁用按钮。

$('button').click(function() {
    //or in the ajax beforeSend function
    $(this).prop('disabled', true);
    $.ajax({
        ...
        //or directly after the user clicked the button
        beforeSend: function() {
            $('button').prop('disabled', true);
        },
        ...
        //complete or success callback
        complete: function() {
            $('button').prop('disabled', false);
        }
    });
});

但是使用这种方法,您应该定义哪个按钮被禁用并且不再可点击。除非您希望禁用所有按钮。我创建了一个working example (jsfiddle)供您测试。(AJAX 完成后有 1 秒的延迟,因此您会注意到禁用的按钮)

使用超时可能是另一种选择,因此如果用户重复按下按钮,AJAX 调用将不会触发。如果 AJAX 调用花费的时间比超时时间长,您的问题仍然存在。

var timer;    
$('button').on('click', function() {
    clearTimeout(timer);
    timer = setTimeout( function() {
        // Run AJAX commonds (May take some time);
    }, 500);

});
于 2013-05-05T18:57:59.433 回答
0

像这样的东西怎么样:(未经测试):

var InProgress = Array();
function OneAtATime($jQueryAjax) {
    var Id = arguments.callee.toString().match(/function\s+([^\s\(]+)/)
    InProgress.push(Id)

    for(var i=0; i<32; i++)
        result += Math.floor(Math.random()*16).toString(16).toUpperCase();
        return result
    }

    CallBacks = {
            success: function(x,y,z){$jQueryAjax.success(x,y,z);Remove(Id);,
            error: function(x,y,z){$jQueryAjax.error(x,y,z);Remove(Id);,
            fail: function(x,y,z){$jQueryAjax.fail(x,y,z);Remove(Id);
        }
}

function Remove(Id) {
    InProgress.splice(InProgress.indexOf(Id),1);
}

样品用法:

OneAtATime({
    /*  Usual jQuery.ajax properties  */
    url: '/Callback';
    success: function(data, status, xhhr) {
        alert('success');
    }

});

正如另一个答案的评论中提到的那样,由于 Javascript 是单线程的,因此不可能出现竞争条件。

于 2013-05-05T19:19:38.597 回答