How to prevent executing an ajax function too often

Viewed 59

function go_save(){
  console.log('saving...');
}

$('button').on('click', function(){
  console.log('clicked');
  //the above should be written each time the button is clicked
  //the next should be executed only if the last click happens 9 seconds in the past
  go_save();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>CLICK</button>

go_save is an ajax function and I want to prevent it to execute if a user clicks on a button several times at once.

But I don't want to wait for console.log('clicked'), only for go_save()

Any help?

5 Answers

You should not do it manually, I will suggest you to disable the button after clicking and enable the button again when the ajax request is complete.

You can check the time differences in seconds in each click of the button. You can ignore the time check for the first click with a flag variable:

function go_save(){
  console.log('saving...');
  time = new Date();
  isFirst = false;
}
var time = new Date();
var isFirst = true;
$('button').on('click', function(){
  console.log('clicked');
  //the above should be written each time the button is clicked
  //the next should be executed only if the last click happens 9 seconds in the past
  var diff = (new Date().getTime() - time.getTime()) / 1000;
  if(isFirst || diff >= 9)
    go_save();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>CLICK</button>

You can use a debounce function like this:

function go_save(){
  console.log('saving...');
}

const debouncedFunction = debounce(go_save, 1000);

$('button').on('click', function() {
    console.log('clicked');
    debouncedFunction();
});

function debounce(func, wait, immediate) {
 var timeout;
 return function() {
  var context = this, args = arguments;
  var later = function() {
   timeout = null;
   if (!immediate) func.apply(context, args);
  };
  var callNow = immediate && !timeout;
  clearTimeout(timeout);
  timeout = setTimeout(later, wait);
  if (callNow) func.apply(context, args);
 };
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>CLICK</button>

You can use setTimeout method:

Edit as per comments:

let clicker = 0;
$('button').on('click', function(){
  ++clicker;
  console.log('clicked');
  if (clicker == 1) {
    setTimeout(function() { // once button clicked, execute go_save() after 9 seconds.
      go_save();
      clicker = 0;
    }, 9000);
  }
});

Old answer:

$('button').on('click', function(){
console.log('clicked');
this.disabled = true; // disabled the clicked button 
setTimeout(function() { // remove it after 9 seconds
        this.disabled = false;
    }, 9000);
//the above should be written each time the button is clicked
//the next should be executed only if the last click happens 9 seconds in the past
go_save();
});

read more on MDN

Use async property in your ajax request. It will wait until your request complete.

See example -

           $.ajax({
                url: base_url+pageUrl,
                type: 'POST',
                dataType: 'json',
                data: { },  
                async: false,
                success: function(response){
                    setTimeout(function(){
                        $('#'+responseDiv).empty().html(response.template);
                    }, 500);
                },
                error: function(){
                    toastr.error("Something went wrong, but we're here to help! Reach out to <a href='mailto:helpdesk@nhpowerhour.com'>helpdesk@nhpowerhour.com</a> We're here for you!");
                }
            });

No need to do something much big. just disabled the button until the work has been finished.here is the code bellow

function go_save(){

  console.log('saving...');
  $('button').removeAttr('disabled');
}

const debouncedFunction = debounce(go_save, 1000);

$('button').on('click', function() {
    console.log('clicked');
    $('button').attr('disabled','disabled');
    debouncedFunction();

});

function debounce(func, wait, immediate) {
 var timeout;
 return function() {
  var context = this, args = arguments;
  var later = function() {
   timeout = null;
   if (!immediate) func.apply(context, args);
  };
  var callNow = immediate && !timeout;
  clearTimeout(timeout);
  timeout = setTimeout(later, wait);
  if (callNow) func.apply(context, args);

 };
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>CLICK</button>

I hope this will help you. if you have any questions you can as me anytime.

thank you.

Sagar Kumar, Software Developer

Related