处理javascript/jquery中的多线程问题

Handling multithreadiing issue in javascript/jquery?

本文关键字:多线程 问题 jquery javascript 处理      更新时间:2023-09-26
$(".getDetails").click(function() {
    // some stuff like fetching response from server
})

当用户在几分之一秒内多次单击UI上的getDetails按钮时,jquery会生成两个click函数调用,我的逻辑失败。我认为解决方案是在第一次点击时禁用按钮本身(这样用户就不能多次点击(。一旦我得到回应,或者就在回来之前通过单击方法,我启用了它。有更好的解决方案吗?

如果没有,我如何使按钮禁用,一旦用户第一次点击按钮。我认为这需要在调用click方法或html元素中的某个where之前完成?

Java提供了synchronized关键字,所以一次只有一个线程进入方法内部,我不确定javascript中是否存在类似的东西?

假设点击处理程序执行AJAX请求,您可以在发出请求之前将按钮设置为禁用,然后在请求完成后再次启用。试试这个:

$(".getDetails").click(function(){}
    var $btn = $(this).prop('disabled', true);
    $.ajax({
        url: '/foo'
        success: function() {
            console.log('It worked!');
        },
        error: function() {
            console.log('It failed!');
        }, 
        complete: function() {
            $btn.prop('disabled', false);
        }
    });
});

您可以尝试取消绑定点击事件,并在ajax调用后再次将点击绑定到该类

$(".getDetails").click(function(){}
$(".getDetails").unbind('click');
 // some stuff like fetching response from server
 )

您可以使用简单的标志来防止多次触发您的逻辑:

var flag = true    
$(".getDetails").click(function() {
  if (flag) {
     flag = false;
     //your logic...
     //when your code ends (in after-AJAX callback for example)
     flag = true;
  }
});
$(".getDetails").click(function(e){
  var $target = $(e.currentTarget); 
  // assuming the click listener is on the button
  $target.prop('disabled',true);
  // request, stuff...and when done:
  $target.prop('disabled',false);
})

尝试阻止默认值并返回false以避免任何其他事件传播这是一个类似于信号量或监视器的解决方案

var progress = false;
$(".getDetails").on('click', function(e) {
if(!progress){       
progress = true;
// some stuff like fetching response from server
//also  after sucessfull fetch make  true to false again
}else{
   console.log('something in progress'); 
}
   e.preventDefault();
   return false;
})

这应该确保您的按钮不会触发异步请求两次,直到您得到响应。

function doAjaxReq() {
  /*
    Add your ajax operation here
    as a return value of doAjaxReq
    like so:
    
    return $.ajax({
      url: '/foo',
      type: 'POST',
      data: data
    })
    
    Since i can't use ajax here let's smilulate
    it useing a promise.
  */
  promise = new Promise(function(res, rej) {
    setTimeout(function(){
      res({foo: "bar"});
    }, 1000)
  })
  return promise;
}
/* 
Inside here you add the click handlder
only once use `elem.one('click'...`
*/
function addClickHandler(elem) {
  elem.one('click', function() {
    // do your ajax request and when its
    // done run `addClickHanlder` again
    // i'm using `.then` because of the promise,
    // you should be using `.done`.
    doAjaxReq().then(function(data) {
      console.log(data);
      addClickHandler(elem);
    });
  })
}
addClickHandler($(".getDetails"));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="getDetails">Get Details</button>