1

So I have a few functions that all make async calls to a service. I wan't them all to execute after the previous one is complete but only if the previous one didn't fail. It looks something like this:

var fn1 = function() {
    var promise = aService.fn1();
    var successCallback = function(response) {
        return true;
    };
    var errorCallback = function() {
        return false;
    };
    return promise.then(successCallback, errorCallback);
};
var fn2 = function() {
    var promise = aService.fn2();
    var successCallback = function(response) {
        return true;
    };
    var errorCallback = function() {
        return false;
    };
    return promise.then(successCallback, errorCallback);
};
var fn3 = function() {
    var promise = aService.fn3();
    var successCallback = function(response) {
        return true;
    };
    var errorCallback = function() {
        return false;
    };
    return promise.then(successCallback, errorCallback);
};

fn1().then(function(resp){
    if (resp)
    {
        fn2().then(function(resp){
            if (resp)
            {
                fn3().then(function(resp){
                    if (resp)
                    {
                        // all functions have been called in order were successful
                    }
                });
            }
        });
    }
});

The execution at the end looks pretty bad the more function are added to this chain. I wan't to know if there is another way I can structure this in way so it behaves the same but doesn't create a huge tree of chained async calls. If I can keep it on the same indentation that would be great. Thank you!

2 Answers 2

3

You have to modify the error callbacks to return $q.reject() instead of false, i.e.:

var fn1 = function() {
    var promise = aService.fn1();
    var successCallback = function(response) {
        // no return needed, unless the next stage
        // requires the results of this stage
    };
    var errorCallback = function() {
        return $q.reject();
    };
    return promise.then(successCallback, errorCallback);
};

The the chaining becomes:

fn1()
    .then(function() {
        return fn2();
    })
    .then(function() {
        return fn3();
    })
    .then(function() {
        // ALL SUCCEEDED HERE
    });

In fact you do not even have to write that painful code in f1, f2, f3, i.e. the following will also do the job:

aService.fn1()
    .then(function() {
        return aService.fn2();
    })
    .then(function() {
        return aService.fn3();
    })
    .then(function() {
        // ALL SUCCEEDED HERE
    });
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! That worked perfectly. I can't use your third solution though as in my real code I have some logic in the error- and success-callbacks of fn1, fn2 and fn3. However the second solution you provided was exactly what I was looking for.
1

If your service functions are already promisified, you can keep things extremely short:

aService.fn1()
.then(aService.fn2.bind(aService))
.then(aService.fn3.bind(aService))
.then(function(){
    // all functions have been called in order and were successful
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.