简体   繁体   中英

Why is then() chained methods not running sequentially?

We are trying to execute a number of AJAX calls in a particular order. The following code has methodA, methodB and methodC (each returns an AJAX promise object running async=true ).

They are chained using the then() function in jQuery .

 self.methodA().then( self.methodB() ).then( self.methodC() )

I have made one of the methods slow ( methodB ) (I use a slow URL).

I would expect A ... 10 second wait...then B then C .

Instead I get A, C ....10 second wait and B .

Why is it doing that? Does it have something to do with me using the alert() in an always() function?

Here is my code in a fiddle : http://jsfiddle.net/h8tfrvy4/13/

Code:

function Tester() {
    var self = this;
    this.url = 'https://public.opencpu.org/ocpu/library/';
    this.slowurl = 'http://fake-response.appspot.com/?sleep=5';


    this.save = function() {
        self.methodA().then( self.methodB() ).then( self.methodC() )
    }

    this.methodA = function () {
        var self = this;

        return $.ajax({
            url: self.url,
            async: true
        }).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {

            //check for errors... and if OK
            alert('A OK');


        })
    }
    this.methodB = function () {
        var self = this;

        return $.ajax({
            url: self.slowurl,
            async: true
        }).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {

            //check for errors... and if OK
            alert('B OK');


        })
    }
    this.methodC = function () {
        var self = this;

        return $.ajax({
            url: self.url,
            async: true
        }).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {
            //OK
            alert('C OK');

        })
    }
}
new Tester().save();

This is wrong:

self.methodA().then( self.methodB() ).then( self.methodC() )

You're invoking each method immediately , and passing the promises into then .

If you want each function to wait until the previous finishes, you need to give each then a callback to execute when the previous promise resolves:

self.methodA().then(function () { return self.methodB() }).then(function() { return self.methodC() });

Short and simple:

this.save = function() {
    self.methodA().then( self.methodB ).then( self.methodC )
}

It has bothered me all **&^*$& day that @meagar was right and I was wrong on this one but I was sure that I was right. His answer seemed too complicated and but I was fuzzy headed in the morning and my answer wasn't right either. This is the right answer and it works perfectly when you plug it into the JSFiddle.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM