Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trigger a function only after the completion of multiple AJAX requests

I've got a particular function I want to run once, and only after the completion of several AJAX requests.

My current solution looks a bit like this:

function doWork() {
    //This is the function to be run once after all the requests
}

//some tracking/counting variables
var ajaxDoneCounter = 0;
var numOfAjaxRequests = 5;
var workDone = false;

function doWorkTrigger() {
    ajaxDoneCounter++;
    if( !workDone && ajaxDoneCounter >= numOfAjaxRequests ) {
        workDone = true;
        doWork();
    }
}

// ...

//and a number of ajax requests (some hidden within functions, etc)
//they look something like this:
$.ajax({
    url: "http://www.example.com",
    dataType: "json",
    success: function( data ) {
        //load data in to variables, etc
        doWorkTrigger();
    }
});

One obvious pitfall in the above is that any AJAX call that is not successful will not increment ajaxDoneCount and so doWork() will probably never be called. I can get around that using the error callback in inside any $.ajax, so that doesn't worry me too much.

What I want to know is whether the above is safe and/or good practice?
Is there a trick I've missed, or any thing else that might work better?

like image 961
DMA57361 Avatar asked Aug 04 '10 11:08

DMA57361


2 Answers

Update: Since jQuery 1.5, deferred objects [docs] provide a cleaner solution. Have a look at an example here.


I would use .ajaxComplete(), it will be triggered whenever an Ajax call completed (success or error):

var numOfAjaxRequests = 5;

$(document).ajaxComplete(function() {
    numOfAjaxRequests--;
    if(!numOfAjaxRequests) {
        doWork();

    }
});

Then you don't have to edit every Ajax request.

You could even use .ajaxSend() to get notified of starting Ajax requests, instead of hardcoding it (but I am not sure whether this really works, maybe you will experience race conditions):

var numOfAjaxRequests = 0;

$(document).ajaxSend(function() {
    numOfAjaxRequests++;
});
like image 159
Felix Kling Avatar answered Oct 10 '22 09:10

Felix Kling


I think you should use complete(XMLHttpRequest, textStatus) ajax event instead of success(data, textStatus, XMLHttpRequest).

According to jQuery help:

complete(XMLHttpRequest, textStatus)

A function to be called when the request finishes (after success and error callbacks are executed). The function gets passed two arguments: The XMLHttpRequest object and a string describing the status of the request. This is an Ajax Event.

like image 40
gyromonotron Avatar answered Oct 10 '22 11:10

gyromonotron