Second jQuery.post request finishing before first one. How to avoid this?

319 Views Asked by At

I'm trying to implement a search bar like facebook for my website users. While you type the name, some results are displayed. To avoid sending a request for each button pressed, i've setup a timeout. The idea is: if i'm going to type jack It doesn't make sense to search for j, ja, jac, jack, but it's better to wait for the users finishes typing before sending any request. Once the request is sent and completes, a div called mydiv is filed with results (the request response). If after some time long enough i type another letter, another request is sent and mydiv is filled with new results.

The idea comes from this question. Here is my simplified implementation.

var thread = null;    

$('#search-user').keyup(function() {
  clearTimeout(thread);
  name = $('this').val(); //i get the name just typed
  thread = setTimeout(function(){ 
    get_data_with_ajax_and_put_it_in_mydiv(name);
  }, 200);              
});

function get_data_with_ajax_and_put_it_in_mydiv(name){
  $.post()....
  /*Do some stuff*/
}

As you can see, after a 200ms timeout the function get_data_with_ajax_and_put_it_in_mydiv(); is called. This function, emptys mydiv before putting new data. It works almost always, but sometimes a strange bug occurs.

I'm going to explain where i think the problem is, by providing a real example. Let us assume that get_data_with_ajax_and_put_it_in_mydiv() takes from 50ms to 1000ms to complete, depending on various factors (network speed, congestion, etc...).

  • At t=0 i type jac and i stop typing.
  • At t=200 the timeout expires and get_data_with_ajax_and_put_it_in_mydiv() runs. In this case it takes 1000ms to run
  • At t=210, because i'm a slow writer, i type the letter k of jack. mydiv is empty because the first request has not yet completed.
  • At t=410 the timeout for the letter k epires and a second request is sent. This time, the function takes 100ms to run.
  • At t=510 the second request finishes and i get the results for jack.
  • At t=1200 the first request finishes and i get the results for jac.

ERROR

As you can see due to impredictability of time elaped by ajax requests i got a wrong result. mydiv is filled with jac results and not jack.

SOLUTION

The first solution that came to my mind is the following: every time i call get_data_with_ajax_and_put_it_in_mydiv() i have to stop any previous request still running. How can i do that? If not possible, how can i fix this error?

2

There are 2 best solutions below

0
On

Why not use a debounced function to handle the ajax call?

http://benalman.com/code/projects/jquery-throttle-debounce/examples/debounce/

1
On

You should use the Promise interface and use the 'done' method to chain these two operations sequentially

http://api.jquery.com/jquery.post/