jQuery Promise then not working after AJAX

2019-03-21 03:12发布

问题:

I have my Promise defined as so:

myFunc = function() {
    $.getJSON("./rest/api/some/url", function(json, textStatus) {
        console.log("AJAX call hit!");
    });
};


$.when(myFunc()).then(function() {
  console.log("Then block hit!");
});

and in console it's being output as:

Then block hit!
AJAX call hit!

I need the AJAX call hit! first followed by the Then block hit!.

Any idea why this is happening? I even tried to implement a custom callback function (a standard example I found on Stackoverflow) and it still doesn't work.

回答1:

I think this question needs a more complete explanation.

$.when() has no magical powers to know when some function you put inside its parens happens to be done. It only works with async operations when you pass $.when() one or more promises that are themselves resolved when the underlying async operation is done.

So, in your code:

myFunc = function() {
    $.getJSON("./rest/api/some/url", function(json, textStatus) {
        console.log("AJAX call hit!");
    });
};

$.when(myFunc()).then(function() {
    console.log("Then block hit!");
});

myFunc() is returning nothing which means undefined, so you're in essence doing:

myFunc();
$.when(undefined).then(function() {
    console.log("Then block hit!");
});

When you don't pass any promises to $.when(), it just resolves immediately (since it has nothing to wait for).

Instead, you need to make sure that myFunc() returns a promise that is resolved when the Ajax call is done. Since jQuery's $.getJSON() already returns such a promise, all you have to do is to return that promise like this:

var myFunc = function() {
    return $.getJSON("./rest/api/some/url", function(json, textStatus) {
        console.log("AJAX call hit!");
    });
};

$.when(myFunc()).then(function() {
     console.log("Then block hit!");
});

Of course, when there's only one promise to wait on, there is no reason to use $.when() at all as it is just extra code getting in the way. $.when() really only adds value when you have more than one promise you want to wait on. So, instead you can just do this:

var myFunc = function() {
    return $.getJSON("./rest/api/some/url", function(json, textStatus) {
        console.log("AJAX call hit!");
    });
};

myFunc().then(function() {
     console.log("Then block hit!");
});


回答2:

You need promise-compatible object functon myFunc() returns null

$.when(null).then(function() {
    console.log("Then block hit!");
});

output : Then block hit!

Try

return $.getJSON("...