Frantisek
Frantisek

Reputation: 7693

Sending jQuery ajax request on keyboard input

I'm sending an ajax request to the server on user's input to an <input> element, like this:

$('#my-input').bind("input", function(event){
   // here's the ajax request
});

What bothers me is that it send unnecessarily many requests on every user's keyup, meaning that if the user types very fast, there are many unnecessary requests. So I get the idea that there should be a certain delay/timeout, which waits a certain time (50 miliseconds?) for the user to stop typing before sending the ajax request. That would be one problem solved.

But what about cases when the first ajax request haven't been completed before sending another request? (Typing 60 ms / char while ajax request taking 300 ms).

What is the best way to solve this problem (both idea- and code-based)?

Upvotes: 4

Views: 1201

Answers (4)

Jibi Abraham
Jibi Abraham

Reputation: 4696

I'd go with @HuiZeng's answer, but just in case you want a slightly modified version.

Steps

  1. Listen to keydown using a setTimeout that you can clear.
  2. When it fires, check if you have a previous request in queue, if so abort it and fire a new one

Example:

var inputTimer = 0, req;

function onInput(e){
      clearTimeout(inputTImer);
      inputTimer = setTimeout( function(){
           // You have access to e here
           // Cancel any previous requests
           req && req.abort();
           req = $.ajax({/*...Do your magic here :)*/})
      }, 100)
 }

Upvotes: 0

sgeddes
sgeddes

Reputation: 62841

You could just use the setTimeout function. Every so often, see if the text hasn't changed, and if it hasn't, then process accordingly.

setTimeout(function() {
      // Do something after 1 second
}, 1000);

Upvotes: 1

Kinjal Bagaria
Kinjal Bagaria

Reputation: 46

You can set async: false in your ajax request so it will process second ajax call only after completion of first ajax request.

Upvotes: 0

Hui Zheng
Hui Zheng

Reputation: 10224

You can use throttle function in underscore library. As its documentation says:

Creates and returns a new, throttled version of the passed function, that, when invoked repeatedly, will only actually call the original function at most once per every wait milliseconds. Useful for rate-limiting events that occur faster than you can keep up with.

Even if you don't want to introduce a new library, you can still get idea about how this function works from its source code. In fact, a simple version of throttle function could be:

function throttle(func, delay) {
    var timeout = null;
    return function() {
        var that = this, args = arguments;
        clearTimeout(timer);
        timeout = setTimeout(function() {
            func.apply(that, args);
        }, delay);
    };
}

This jQuery throttle-debounce plugin is also helpful. Especially, the debounce function seems more suitable to your needs than throttle function according to its author:

Debouncing can be especially useful for rate limiting execution of handlers on events that will trigger AJAX requests

Upvotes: 3

Related Questions