Handling multithreading issue in javascript / jquery?

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

when the user presses the getDetails button on the user interface several times for a split second, jquery generates two calls for the click function and my logic crashes. I think the solution to this would be to disable the button on the first click (so use cannot click several times). As soon as I get a response or just before returning from the click method, I turn it on. Is there a better solution?

If not, how can I disable the button as soon as the user clicks the button for the first time. I think this needs to be done before calling the click method or somewhere in the html element?

Java provides a synchronized keyword, so that only one thread enters a method inside time, I'm not sure if a similar thing exists in javascript or not?

+4
source share
6 answers

Assuming the click handler is executing an AJAX request, you can set the button as disabled before executing the request, and then turn it back on after the request completes. Try the following:

$(".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);
        }
    });
});
+2
source

you can try unbinding click event and after the ajax call will again connect with a click on this class

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

, :

var flag = true    
$(".getDetails").click(function() {

  if (flag) {
     flag = false;
     //your logic...

     //when your code ends (in after-AJAX callback for example)
     flag = true;
  }

});
0
$(".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);
})
0

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;

})
0
source

This should make sure that your button will not run the asynchronous call request twice until you get a response.

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 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>
Run codeHide result
0
source

Source: https://habr.com/ru/post/1649873/


All Articles