Question

I have 2 ajax calls that I am attaching via $.when to perform some tasks when they are finished.

The code looks like this:

function ajaxCall(url, targetDiv) {
    dfd = new $.Deferred();
    $.ajax({
        url:url
        success : function(data) {
            dfd.resolve(data, targetDiv);
        }
    })
    return dfd.promise()
}

d = ajaxCall('/somewhere/', 'myDiv');
d2 = ajaxCall('/somewhere/else', 'myNewDiv');
$.when(d, d2).then(function(){alert('all done');})

In this scenario we never have the alert all done called. We are following roughly the outline on https://api.jquery.com/deferred.promise/

When checking this we can see that neither d nor d2 will ever call done (if we attach a done to them) however the success part of the ajax call is called.

Was it helpful?

Solution

Syntax analyzer mode... STOP!

function ajaxCall(url, targetDiv) {
    dfd = new $.Deferred(); // <-- Wait, a global variable?

Second ajaxCall(...) is setting a different Deferred instance, and first deferred won't never be resolved (you're setting the same variable twice, so .resolve(...) is called on the second ajaxCall(...) function call only and you're not resolving the first deferred object because it's gone!).

Solution:

function ajaxCall(url, targetDiv) {
    var dfd = new $.Deferred(); // <-- Oh! A local variable... :)

Do you want a good suggestion? Always declare variables with var, since variables declared in a function scope will be added to the function instance, instead of window object:

// Both sentences are equivalent in a function scope (or in the global scope)
a = "hello";
window.a = "hello"; 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top