views:

1420

answers:

2

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?

+4  A: 

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.

Alan Storm
+2  A: 

Here is another option. Code may need to be tweaked, I didn't actually test it, but it's a start.

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
     })
    } 
}
Philip T.