user736893
user736893

Reputation:

ajaxStop fires twice... sometimes

Based on the issue in this question (ajaxStop was firing twice), I wrote the following ajaxStop event.

var ajaxCount = 0;

$(document).ajaxStop(function () {
    ajaxCount += 1;
    console.debug('calling ajaxStop, iteration ' + ajaxCount);
    if (ajaxCount == 2) {
        $('.fieldLoading').hide();
        $('.fieldValue').show();
    }
});

9 times out of 10 it works exactly as expected. The debug console shows "calling ajaxStop, iteration 1" as soon as the page loads. Then, after everything else fires, it shows "calling ajaxStop, iteration 2". This is what I expect. However, about 5 or 10 percent of the time it only displays iteration 1, after everything has fired (which means no data is shown).

Upvotes: 0

Views: 754

Answers (2)

user736893
user736893

Reputation:

I ended up using a queue like so:

var ajaxQueue = $({});

$.ajaxQueue = function (ajaxOpts) {
    // Hold the original complete function.
    var oldComplete = ajaxOpts.complete;

    // Queue our ajax request.
    ajaxQueue.queue(function (next) {
        // Create a complete callback to fire the next event in the queue.
        ajaxOpts.complete = function () {
            // Fire the original complete if it was there.
            if (oldComplete) {
                oldComplete.apply(this, arguments);
            }
            // Run the next query in the queue.
            next();
        };

        // Run the query.
        $.ajax(ajaxOpts);
    });
};

Now I just call all my ajax events as ajaxQueue() instead of ajax(). Then, I have a $(document).ajaxStop() that I use to finish everything up.

Upvotes: 0

Pete Scott
Pete Scott

Reputation: 1526

I suggest adding an ajaxSend() handler to count the number of ajax requests and converting the ajaxStop() to an ajaxComplete(). Rather than performing:

if (ajaxCount == 2) 

You can then do:

if (ajaxStopCount == ajaxStartCount)

Additionally, you could modify your counters to count ACTIVE requests (decrement the counter on ajaxComplete, increment it on ajaxSend (your loading dialog might disappear between requests, but will re-appear as soon as another request begins; I wouldn't image much of a delay between hiding/showing, but that depends on your code organization).

Add another handler for errors, and you should be set.

Upvotes: 1

Related Questions