Stop an ajax request and create a new one

Asked

Viewed 341 times

1

In a search input, an ajax request is made at each letter pressed through a Keypress in the field, but at each key pressed a new request is made, ie if the user type fast, and he type a value of 10 letters, 10 different requests will be made, and the same 10 will be processed and sent back by my PHP, and this may cause me some confusion in the return of this data to the user if a previous request is processed late, so I want every keystroke pressed, previous requests are aborted and then send the new request.

$(document).on("keypress", ".meuInput", function(){
    var val = $(this).val();
    if(val != ''){
    jQuery.ajax({
        type: "POST",
        url: "meuarquivo.php",
        datatype: "json",
        data: {src: val},
        success: function(data)
        {
            //processa retorno
        }
    });
});

2 answers

1


Leo, the $.ajax returns an object of type jqXHR, and for reasons of compatibility it maintains some methods and properties in common with the XMLHttpRequest, among them the .abort().

var jqRequest = null;
$(document).on("keypress", ".meuInput", function(){
    var val = $(this).val();
    if(val != ''){
        if (jqRequest)
            jqRequest.abort();
        jqRequest = jQuery.ajax({
            type: "POST",
            url: "meuarquivo.php",
            datatype: "json",
            data: {src: val},
            success: function(data)
            {
                //processa retorno
            }
        });
    }
});

but note that in this case, there is no control of which input called this function, so it might be interesting to maintain a more refined control.

var inputs = [];
var jqRequests = {};

$(document).on("keypress", ".meuInput", function(e){
    var val = $(this).val();
    if(val != ''){      
        if (inputs.indexOf(e.currentTarget) == -1)
            inputs.push(e.currentTarget);
        var indice = inputs.indexOf(e.currentTarget);
        if (jqRequests[indice])
            jqRequests[indice].abort();         
        jqRequests[indice] = jQuery.ajax({
            type: "POST",
            url: "meuarquivo.php",
            datatype: "json",
            data: {src: val},
            success: function(data)
            {
                //processa retorno
            }
        });
    }
});

and finally, your application would perform better if you add a small delay before performing the AJAX request.

var myDelay = null;
$(document).on("keypress", ".meuInput", function(){
    var val = $(this).val();
    if(val != ''){
        if (myDelay)
            window.clearInterval(myDelay);
        myDelay = window.setTimeout(function () {
            myDelay = null;
            jQuery.ajax({
                type: "POST",
                url: "meuarquivo.php",
                datatype: "json",
                data: {src: val},
                success: function(data)
                {
                    //processa retorno
                }
            });
        }, 2000);
    }
});
  • The third option, with delay in the request has no need to abort the requests?

  • 1

    @Leoletto the delay serves to prevent AJAX requests being made while the user is still typing, in the example above the AJAX request will be made 2 seconds after the user finishes typing.

  • If I reduce this delay to 500, would I lose some performance? Because 2 seconds I found it a little big

  • @Leoletto does not exist an ideal value, just remember that small interruptions are normal while you type, so 0.5s can be a short time for some users, so the ideal is to seek a good balance point

  • I think I will opt for the second option and post each letter typed, and interrupt it, gives an impression of a faster return and solves the problem of excessive requests, Thanks for the help

  • @Leoletto I think it doesn’t solve, you know, make a .abort() does not mean that the request on the server side will be stopped, if it has already been delivered, PHP will do all its work, but the browser will ignore the return.

  • an option to relieve the server side, is to set a minimum size to search, type 3 letters, with a range of 0.5s and at least 3 characters, I believe will have a good performance relationship with user experience.

  • The problem of limiting the characters is that the values to be searched can vary understand? If the user wants for example to search all the results with the letter A and I limit the search 2 or more characters he will not have access to the results by letter, this solution is more for people with slower internet

  • I tested on connections 5mb above, requests are sent and processed in the order they were typed, but below that some new ones are sent before the previous ones, causing a bug in the view

Show 4 more comments

-1

Try this:

$(document).on("keypress", ".meuInput", function() {
  var val = $(this).val();
  if (val != '') {
    setTimeout(minhafuncao, 500);
    //não coloque () ou a função vai ser executada ignorando os 500ms.
  }
});


var minhaFuncao = function() {
  jQuery.ajax({
    type: "POST",
    url: "meuarquivo.php",
    datatype: "json",
    data: {
      src: val
    },
    success: function(data) {
      //processa retorno
    }
  });
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.