Why jQuery.then () behaves differently when using $ .deferred and $ .ajax

I am trying to plunge into a jQuery Deferred object. I intend to check every ajax answer (success / failure). I want to do this without interfering with other code declaring a typical $ .ajax () request. Done (). Fail ().

I have $ .ajaxPrefilter () to get every ajax request before it executes. Using the .then () method for the jqXHR object, I managed to add a function that will be called before the .done () method placed on the original call to $ .ajax ()

The code below will print the following:

def done
def then
Second pre-filter ajax, then
2nd ajax

2nd ajax, then
ajax done
ajax then

What I don't understand is why the pre-filtering step is performed first. I expected it to be executed last or not at all.

Behavior is what I want, but I don’t understand why.

// this is a typical usage of deferred with two done functions added, the second via .then()
var def = $.Deferred();
def.done(function(){
    document.write("def done<br>");
});
def.then(function(){
    document.write("def then<br>");
});
def.resolve();

// this is a typical ajax request with a done function added, followed by another using .then()
$.ajax("/echo/json/").done(function(){
    document.write("ajax done<br>");
}).then(function(){
    document.write("ajax then<br>");
});

// for the third request i intercept and call the .then() method 
$.ajaxPrefilter( 
    function( options, originalOptions, jqXHR ) {
                jqXHR.then(function(data, textStatus, jqXHR){
                     document.write("2nd ajax prefilter then<br>");
                    });
            });

// create a typical ajax request. these will be executed after the prefilter .then()
$.ajax("/echo/json/").done(function(){
    document.write("2nd ajax done<br>");
}).then(function(){
    document.write("2nd ajax then<br>");
});

Thank you in advance for your help.

UPDATE: ------------

From @Bergi's answer, the code below demonstrates how $ .ajaxPrefilter () is called before executing ().

$.ajaxPrefilter( 
    function( options, originalOptions, jqXHR ) {
            document.write("prefilter function within $.ajax call<br>");
                jqXHR.then(function(data, textStatus, jqXHR){
                     document.write("2nd ajax prefilter then<br>");
                    });
            });

var functionToRunWhenDoneIsCalled = function() {
    document.write("done is called function<br>");
    return function(){
       document.write("2nd ajax done<br>");
    }
}

$.ajax("/echo/json/").done(
    (functionToRunWhenDoneIsCalled)()
).then(function(){
    document.write("2nd ajax then<br>");
});

It is output:

The prefilter function in the $ .ajax call
made is called the
Second Ajax prefilter function , then
2nd Ajax,

2nd Ajax, then

Answers my question about how the .then () method is bound to the pending jqXHR object before the .done () method.

+5
source share
3 answers

.done() .then(). .done() .

, , - , . , .

. $.ajax, .. , $.ajax , done then .

+3

.then, , / . , .then, , , $.ajax(), . .

+1

, , - , . , .

jqXHR, ajax, ​​ . , /, ajax. , , .

, prefilter .then(), , - . , , ( ) .

ajax, . , .

+1

All Articles