2

i m using jQuery Slider. on its "change" event im doing some heavy JavaScript - making an ajax call to function (let's call it A) and get results from database (actually from Cache to make it smoother).

the thing is, on our Stress-Test we found that if we play with the slider a lot, move it from right to left quickly - it makes many many asynchronous JavaScript calls to the client that resulted in many queries to the server that leads to broken UI as a result.

after a lot of time for testing this issue it seems that, if i would set a timeout between the calls - it works OK.

so im wondering what should i do to avoid this? how can i be sure that if the user makes this scenario he won't see a broken UI?

maybe i should use "deferred" of jQuery 1.5 to check the state of the first call to function A and wait until it finish, before i'll execute the second call for that function?

it's only a thought.

Yaniv
  • 1,906
  • 2
  • 16
  • 23

4 Answers4

2

One solution is to make the Ajax call only if the slider was not changed for a certain time, lets say 200ms (choose an appropriate threshold).

This is called debouncing and Ben Alman create a nice jQuery plugin which lets you integrate this easily.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
1

Have you checked out the Hover Intent Plugin? It is designed primarily to prevent this type of behavior from happening

http://cherne.net/brian/resources/jquery.hoverIntent.html

javram
  • 2,635
  • 1
  • 13
  • 18
1

There are multiple possible solutions here:

Debouncing

Only send the ajax call when the slider has stopped moving for a certain amount of time. This prevents rapid sending of ajax calls and guarantees that ajax calls are never sent with less than xx time between them. This type of behavior is common for handling scroll events when you can't update the state fast enough when scroll events come piling in too fast. Upon each event, this involves managing a timer that will be set when the slider has moved and then will fire if it stops moving for a certain amount of time and is reset every time the slider moves some more before the pause time elapses.

Single Ajax Call In-Flight At a Time

Sometimes, the desired behavior is that once you've sent an ajax call, you don't send another one until the current one is done. This generally involves keeping some sort of flag that indicates whether one of your ajax calls is already in flight. If you detect that the slider has moved, but an ajax call is in flight, you set another flag that says that an ajax call is pending. When each ajax call completes, it clears the inFlight flag and checks the pending flag to see if one more ajax call should be sent. Proper error handling is critical here so the inFlight flag can never get stuck.

Force the Ajax Responses into Proper Order

Because ajax calls are asynch, there is no guarantee that responses will be received in the same order as the requests were sent and this can sometimes mess up the results. If it's still desirable to send lots of the ajax events (so you don't want to use either of the previous options), but the results must be in proper order, then the results can be forced into proper order. This involves tagging each ajax request with some sort of sequence number and then queuing results that arrive out of order until they precedents arrive. This is fairly complicated and I would not recommend it if not absolutely required. The previous options are much simpler to implement.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • ok, and which one is better? Debouncing ot Single call In-Flight? actually i tend to implement the second one, since the first one sounds like a overhead delay for the system. how can i force the change of that flag to be held by a single function? (like sema-fore). everyday it seems to me that handling with javascript is the same as handling with threads. – Yaniv Mar 15 '12 at 07:16
  • @Yaniv - which one is better depends upon which type of implementation you want as they all have different features. Javascript is single threaded so you do not need to worry about concurrency in setting the flag. Only one piece of javascript ever runs at a time and it runs to completion until the next scheduled piece runs. You can read more about the single threadedness here: http://stackoverflow.com/questions/7575589/how-does-javascript-handle-ajax-responses-in-the-background/7575649#7575649 – jfriend00 Mar 15 '12 at 14:57
0

When the slider moves, store the value of the slider and wait for a short period of time (Lets suppose 500 ms), if there is no movement in that time period then call the web service, otherwise if the person moves before 500 ms is up, just reset the stored value of the slider and wait another 500 ms.

Ali Khalid
  • 1,345
  • 8
  • 19
  • that will cause a 500 ms delay before calling the function that brings the data from the server, which will take another certain of time. – Yaniv Mar 15 '12 at 07:09
  • Agreed, the 500 ms delay was just an arbitrary value. You can choose a smaller or larger value as you see fit. – Ali Khalid Mar 15 '12 at 08:09