#1
  1. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2011
    Posts
    158
    Rep Power
    98

    AJAX queue not quite ASYNC


    Hello all,

    Is it possible to make an AJAX call execute it's callback function before a previous AJAX call executes it's callback function?

    I have 3 generic AJAX queries that take different lengths of time to execute.

    The initial load gathers data from the server on load and displays it. This data set is a fairly coarse level of data and allows the user to drill down into the data set.

    There is the option to get a more fine date set, but it's much larger so it takes longer to download and I would like it to be seamless, but I'm having issues with this.

    My current plan of action is to execute the coarse ajax call and the fine ajax call at the same time.

    The coarse AJAX call completes in less than half a second and displays the data. The fine AJAX call takes about 5 seconds to download locally - it's fairly large data sets. If the user clicks on coarse data items, it executes another AJAX call for very small sets of data, however, the data will not update until the fine data AJAX call completes.

    Based on my testing this is what I'm seeing:
    On their own the execution times are approximately as follows:
    AJAX_1: 0.3s
    AJAX_2: 5s
    AJAX_3: 0.1s

    AJAX_1 call
    AJAX_2 call
    AJAX_1 callback call 0.3s
    //User clicks item displayed by AJAX_1 callback call
    AJAX_3 call
    At this point, AJAX_3 should return and the callback be called.
    AJAX_2 callback call 5s
    AJAX_3 callback call 3s

    The 3s on AJAX_3 callback call isn't executed until AJAX_2 callback call has completed. Right now this is just an alert for testing.

    How can I get around this lag time between AJAX_2 and AJAX_3? I want the user to be able to interact with the website normally as if AJAX_2 wasn't called, unless they request AJAX_2 data, in which case they will have to wait.

    Is it possible to make an AJAX call execute it's callback function before a previous AJAX call executes it's callback function? I'm using jQuery and d3 to execute the AJAX calls, but I could just as easily execute it manually or with another library.
  2. #2
  3. A Not To Shabby Code Smurf
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Aug 2008
    Posts
    1,183
    Rep Power
    184
    Look into jQuery's deferred.done() API; that should allow you to set-up your next AJAX call(s), based on when the previous call is completed/done.
  4. #3
  5. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2011
    Posts
    158
    Rep Power
    98
    That's the complete opposite of what I'm looking for and provide functionality that I'm already seeing.

    What I want to be able to do is execute the callback of a later ajax call - AJAX_3 in my example - before a previously called AJAX request is complete - AJAX_2 in my example. When AJAX_2 is called, it's possible it will complete before any other AJAX calls, but if there are other AJAX calls, I want them to complete and not have to wait.

    The two are completely unrelated and the only reason AJAX_2 is running in the first place is to avoid a longer than optimal load time when the user requests more specific data.

    Think of it in terms of AJAX_1 callback is:
    function DisplayCoarseData
    AJAX_2 callback is:
    function PreloadFineDataForDisplay
    AJAX_3 callback is User-Interaction-Dependent on the data displayed by DisplayCoarseData:
    function InteractWithCoarseData

    I want to run them

    So when the page loads. AJAX_1 runs, returns and executes it's call back. At the same time AJAX_1 was called, AJAX_2 was called, because it takes a much longer time to execute and it's data that's preemptively being called. While AJAX_2 is still running, I want the user to be able to interact with the data displayed by AJAX_1, which makes another ajax call - AJAX_3, and executes it's callback possibly before AJAX_2 is finished. It's possible that there will be no AJAX calls after AJAX_2, but it's possible that the user will interact with several pieces of data before AJAX_2 comes back.

    So if the AJAX calls are made consecutively(1 through 5) I don't want their callbacks to be made in the same order. It's possible that the proper order of execution is AJAX_1, AJAX_3, AJAX_4, AJAX_5, AJAX_2. This is because AJAX_3 through AJAX_5 are calls made based on interactions of the data from AJAX_1. I want the call backs from AJAX_3 through AJAX_5 to execute irrespective of the status of AJAX_2. I don't want them to have to wait until AJAX_2 is complete. AJAX_2 has no effect on the outcome of AJAX_1, 3, 4, or 5. Except what I'm seeing is that AJAX_2 is holding up AJAX_3, 4, 5.
  6. #4
  7. A Not To Shabby Code Smurf
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Aug 2008
    Posts
    1,183
    Rep Power
    184
    You may not need the deferred.done() API, but I still think you are going to have to use the Deferred Object; to accomplish what your wanting to do.
  8. #5
  9. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2011
    Posts
    158
    Rep Power
    98
    Maybe I'm missing something, but how is a deferred object going to help me?

    Let's take a piece of sample code:
    JavaScript Code:
     
    $.getJSON(AJAX_URL_0, function(result){
     
            $.getJSON(AJAX_URL_1, function(result){//callback code});
     
            var deferred = $.ajax(AJAX_URL_2);
     
            deferred.done(function(){
                	alert('done LONG json call');
            });
     
            //for testing purposes I'm only recalling the first AJAX/JSON call which should theoretically take the exact amount of time with variances due to environment factors.
            $.getJSON(AJAX_1_URL,function(result){//callback code});
    });


    The second JSON/AJAX call is NOT being executed until after the first, very long, JSON/AJAX call is being called. All this does is reverse the order in which the call backs are executed. I want to remove the wait time between the first and second, in the above code.

    Here are results of my AJAX queries on my machine.
    Originally Posted by Firebug Console
    GET http://AJAX_URL_0
    200 OK
    75ms

    GET http://AJAX_URL_1
    200 OK
    28ms

    GET http://AJAX_URL_2
    200 OK
    6.38s <--- See how it takes a long time, this is expected and is the only reason AJAX_URL_2 is being called when the page loads. I am tyrying the deferred = $.ajax;deferred.done(callback(){}); You suggested


    GET http://AJAX_URL_1
    200 OK
    6.55s <--- See how even though it only took 28ms up above, the exact same call as above now waits for AJAX_URL_2 to complete before executing? In theory this would be a user-action-result AJAX call that the user would expect to complete in 0.028 seconds.
    Even if I make the second call of AJAX_URL_1 another deferred object, it still waits for the first deferred object to be complete. Am I missing something?
  10. #6
  11. A Not To Shabby Code Smurf
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Aug 2008
    Posts
    1,183
    Rep Power
    184
    I was saying use the deferred object; not necessarily the done() API. Look at the then() API; it will: "Add handlers to be called when the Deferred object is resolved, rejected, or still in progress". So, you should be able to add a handler to trigger another AJAX function; while the previous AJAX function(s); is "still in progress".
  12. #7
  13. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2009
    Location
    Jakarta, Indonesia.
    Posts
    218
    Rep Power
    32
    Wow, thanks for the info about deferred object. I guess this is the next jQuery animal I should start to learn about.

    Regarding to this issue, I'm just wondering whether it could be solved by splitting the ajax into 2 ajax objects; that is by using 2 separate javascript variables. One ajax shall have its own requests/ responses going out and in to its own object, not depending on requests/responses of the other, right?

    So maybe the scheme would be like this... Both 'Coarse' and 'Fine' ajax run at start at the same time. One of the difference between the two is that 'Fine' will set a flag indicating its complete state. So when 'Coarse' has completed, and a user choose to execute a function which requires the result of 'Fine', it could check the flag and decides.

    Hendra
    Last edited by hdewantara; March 29th, 2013 at 12:50 PM.
  14. #8
  15. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2011
    Posts
    158
    Rep Power
    98
    I put this on the back burner as I've decided to approach the problem from another more efficient angle. This proved to be successful, however, I've come to a situation where the only solution is to preemptively make an ajax call once the data is enabled while still allowing faster ajax queries to be started and complete before the slower preemptive call completes.

    Once I have completed this I will update this post with my results trying to use the deferred object as you've explained.

IMN logo majestic logo threadwatch logo seochat tools logo