8

Is there a pattern or standard way to handle Ajax race conditions? Take the following example. You have two tables. Clicking a row on table 1 removes the data from DB and then updates table 2 (which would now be showing all the rows of table 1 less the row that was clicked).

If someone where to click a bunch of rows in fast succession you could get a scenario where table 2 doesn't update for all the clicks do to timing/lag issues.

What might be a good way to approach this? I was thinking of using a possible queue but that kind of defeats the purpose of doing it asynchronously. However I would still have the benefit of the UI not locking.

  • AJAX and databases? How do the two come together in this? – Oded May 11 '12 at 20:13
  • yea i was kind of vague. Its a web app with data being sent/retrieved via ajax more specifically jQuery.get/post. – Ominus May 11 '12 at 20:23
8

Just a thought, perhaps you could create a list for your Ajax callback methods. You would wrap your actual Ajax callback in a method that adds that callback to a slot in an list.

This list waits for callbacks in a specific order and only executes if the top element (the callback you want called first) is filled.

  • 1
    Programmatically nesting the callbacks is a solid solution. – Sam May 11 '12 at 20:23
7

This is not a race condition.

A race condition would occur when the behavior between two asynchronous threads becomes undefined. You can solve this problem by nesting the callback from the first call

  • 6
    Not all AJAX calls will complete at the same speed due to possible network hiccups. We see it even in development on our local network, where a later AJAX call will finish before an earlier one, and the UI ends up wrong. Nesting/queueing callbacks will solve it, but this is a race condition. – Izkata May 11 '12 at 21:57
  • 1
    @Izkata This is incorrect, Javascript does not have race conditions because it runs on a single thread. The situation you're describing is akin to running two functions at the same time, one to open a file, and one to read the contents of the opened file. The file open function must run before the read function, but executing both at the same time means that sometimes the second function will run first. This is not a race condition, it's failing to order things properly. The correct answer for Javascript in 2017 is to use Promise.then() to run async callbacks in the correct order. – Daniel T. Feb 14 '17 at 3:49
  • 1
    @Izkata It's not a race condition, it's an ordering issue. The request itself is handled natively by the browser, but the callback runs in the JS thread. Race conditions are caused when two threads running simultaneously share the same resource and read/write to the resource at the same time, leading to non-deterministic output. If you have two simultaneous AJAX requests, the output is deterministic; it's either the result of callback A, or callback B. What you don't know is the order that the callbacks will be invoked. This is no different than providing two buttons to the user and – Daniel T. Feb 17 '17 at 22:50
  • 1
    not knowing which button the user will click on first. The result will either be the callback for button A, or the callback for button B, but never an unpredictable, non-deterministic output. If you need to control the order that callbacks are invoked in, then you need to use promises. But unpredictable callback invocation timing is not the same thing as race conditions. – Daniel T. Feb 17 '17 at 22:53
  • 1
    @Izkata An 'unexpected result' in a race condition means that a function is non-deterministic, something that doesn't happen in JS because of exactly what you said: "when any concurrent behavior can cause an unexpected result". The keyword here is concurrent; AJAX requests are concurrent, the callbacks are not. Therefore, the result of callback functions in JS are always deterministic because they are executed sequentially, never concurrently. This post is a good read: blog.raananweber.com/2015/06/17/… – Daniel T. Feb 19 '17 at 13:35
6

Generally speaking callbacks are universal tool for dealing with async task's and indeed callbacks is the mechanism to handle AJAX requests in JavaScript. In the context of the callback you can even have reference to the row that is clicked(if closed in closure). You can find the following articles useful: jQuery deferred and Using Deferreds in jQuery

One other thing that you should have in mind, if the user is allowed to click multiple buttons, is that multiple request will be started. However different browsers can handle different number of AJAX requests simultaneously: concurrent-ajax-xmlhttprequest-requests. To overcome this you should implement some basic request queue.

  • +1 for being the only one talking about deferred stuff. – Florian Margaine May 14 '12 at 8:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.