Possible to get notified when jquery $.get ajax calls are done?

Posted in Help the coder! on Feb 21, 2009 at 12:05 IST (about 1 year ago). Subscribe to this post Bookmark and Share Email
Showing comments 1 to 4 of total 4 on page 1 of 1
Post reply
« Previous1Next »

ratheesh
Rank: 234

I have a php / mysql / jquery web app that makes 13 ajax queries to various APIs and stores the result in a database table. To each result I assign a score and when all the results have completed I want to display a 'total score'.

My problem is knowing when all the ajax queries have completed and all the results are in and ready to be tallied.

Here's the existing workflow:

  1. User enters data in the query box and hits submit.
  2. Page reloads and inserts a 'scan id' into a 'scan_index' table.
  3. Page then executes a jquery $.get function for each of 13 queries ( all queries use the same javascript function to perform their work ).
  4. As each result is returned, the result is inserted into a 'scans' table using the previously inserted 'scan id' to allow association with the proper scan. The result is also displayed to the user along with that result's score.

At this point what I would do is retrieve all results in the scans table using the scan_id value, and total up the score and display that to the user.

But my problem is knowing when to kick off the query to retrieve all the totals. Any given query could take up to 10 seconds ( my predefined timeout value ) before completing ( or failing ), but they usually take only about 3 seconds max to complete.

So, without knowing when a query will complete, how can I tell when all queries have completed?

Posted by ratheesh on Saturday, February 21, 2009, 12:05 pm
  • Currently 0.00/5

0 votes

Thank this userFlag this comment

crawlbird
Rank: 302

Easiest way is to just increment a counter for every request to be made, and decrement it for each request completed. When the counter reaches 0, you're done.

// i wait, i wait, i wait, i wait...
var PatientBoy = (function()
{
   var pending = 0;
   var callbacks = [];

   return {
      //
      // Increments the reference count
      // Returns a function to be called upon completion of the event
      newEvent : function()
      {
         ++pending;
         return function() 
         { 
            --pending;
            if ( !pending )
               $.each(callbacks, function() { this() });
         };
      },
      //
      // Stores a function to be called when all pending events
      // are completed.
      onDone : function(callback)
      {
         callbacks.push(callback);
      }

   };
})();

// add several pending events. setTimeout used 
// in this example rather than AJAX calls to illustrate
// that it doesn't matter which order events are completed
setTimeout(PatientBoy.newEvent(), 10);
setTimeout(PatientBoy.newEvent(), 3000);
setTimeout(PatientBoy.newEvent(), 1000);
setTimeout(PatientBoy.newEvent(), 1000);
setTimeout(PatientBoy.newEvent(), 1500);

// set up our callback. When all events added above are complete,
// do something useful.
PatientBoy.onDone(function()
{
    alert('Function is the key...');
});
Posted by crawlbird on Sunday, February 22, 2009, 7:24 am
  • Currently 0.00/5

0 votes

Thank this userFlag this comment

rupamini
Rank: 472

It sounds like the key piece of information you're missing is the callback functionality of $.get. You can specify a function as the second or third argument which will fire when the request has completed

$.get('http://example.com/data', {'foo':'bar'}, function(resonseData){
    //code here will be called when the ajax call has completed
})

So you'll want to setup a counter variable somewhere that gets incremented by one once for each request that's made, and then in the callback will decrement this value by one.

Then, after you've made the final get request, setup a watcher using setInterval that will check periodically (once a second, say) to see if the counter is zero. If it is, you're done with all your requests. You could probably add this check to the $.get callback itself, but that seems like it might be susceptible to timing issues.

That's the basic solution, but this could easily be abstracted out into a more robust/elegant queuing solution.

Posted by rupamini on Monday, February 23, 2009, 2:54 am
  • Currently 0.00/5

0 votes

Thank this userFlag this comment

terragen
Rank: 373

Here is another option.

var complete = 0;

function submitRequests () {
$.get("http://server/query1", {"data": "for Query"}, processResult(1));
$.get("http://server/query2", {"data": "for Query"}, processResult(2));
//...
$.get("http://server/query13", {"data": "for Query"}, processResult(13));
}

function processResults (query) {
complete += Math.pow(2,(query-1));
if (complete == 8191) {
$.get("http://server/results", scanid, function() {
//Show results
})
}
}
Posted by terragen on Monday, February 23, 2009, 12:54 pm
  • Currently 0.00/5

0 votes

Thank this userFlag this comment
Pages: « Previous1Next »

Post your comment (No registration required)

  Add my comment  

TechieDesi Community

Not signed in (Sign-in or Register)
Be a true TechieDesi!
Top 10 Users
Spread the word
Invite your friends
Fan stuff
Help us improve
Need Help
FAQ's
Search tips
Found a bug? Report!
Feeds and letters
Subscribe via RSS
Archives
Subscribe to newsletter
Unsubscribe e-mail
Miscellaneous
Privacy policy
Visit rootnerve
About us
About us
Support the development
Official Blog
Advertise with us
Careers
Copyright (c) 2008, TechieDesi.com. All rights reserved | About us | Do-Not-Disturb registry | Powered by rootnerve | Page rendered in 0.101 seconds