Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Break out of a Promise "then" chain with errorCallback

-- EDIT --

I encountered a weird thing recently about promises, but I guess it's maybe because it's against the philosophy of promises.

Considering the following code :

// Assuming Auth is just a simple lib doing http requests with promises
Auth.signup()
 .then(succCall, errCall)
 .then(loginSucc, loginErr)

// My callbacks here
function succCall (){
 // OK, send second promise
 console.log('succCall');
 return Auth.login();
}

function errCall(){
 // I do some things here and now
 // I want to break out from here
 console.log('errCall');
}

function loginSucc(){
 // This is the callback of the login method when it went OK
 // I want to enter here ONLY if with go through the succCall
 console.log('loginSucc');
}

function loginErr(){
 // This is the callback of the login method when it went not ok
 // I want to enter here ONLY if with go through the succCall
 console.log('loginErr');
}

Here if something goes wrong in Auth.signup(), this is what show :

  • errCall, loginSucc

if i do a $q.reject() in the errCall this is what happens :

  • errCall, loginErr

and this is what i want :

  • errCall... finish, stop here

Now, the problem is, it goes in errCall when signup goes wrong, that's good, but then it enters loginSucc...

I want to break out of the then chain when any errorCallback (which is errCall or loginErr here) is encountered.

-- EDIT --

I think i was misunderstood by some mean, i want to totally break the chain without check in any other "then" if something went wrong.

As if i was saying : if first then is wrong stop here, if first then ok continue, if second "then" ok continue, if third "then" wrong, stop

// Just like if i did the following but by chainning "then" methods
// My callbacks here
function succCall (){
 // OK, send second promise
 return Auth.login().then(loginSucc, loginErr);
}

My point is, i don't want only one error handler if i have many "then" chained

like image 329
darkylmnx Avatar asked Dec 21 '15 15:12

darkylmnx


People also ask

Can promises be chained?

Example 2: Chaining the Promise with then() Promise resolved You can call multiple functions this way. In the above program, the then() method is used to chain the functions to the promise. The then() method is called when the promise is resolved successfully. You can chain multiple then() methods with the promise.

What is Promise chaining give an example?

Chaining after a catch It's possible to chain after a failure, i.e. a catch , which is useful to accomplish new actions even after an action failed in the chain. Read the following example: new Promise((resolve, reject) => { console. log("Initial"); resolve(); }) .

What is chaining of Promise?

Promise chaining: Promise chaining is a syntax that allows you to chain together multiple asynchronous tasks in a specific order. This is great for complex code where one asynchronous task needs to be performed after the completion of a different asynchronous task.


1 Answers

What is effectively happening is this:

    try {
        try {
            var a = succCall();
        } catch(e1) {
            a = errCall(e1);
        }
        var b = loginSucc(a);
    } catch(e2) {
        b = loginErr(e2);
    }

You can break out of the chain by calling

return $q.reject('Reason Err was called');

in your errCall() function.

EDIT: As OP remarked by calling $q.reject the code will enter the loginErr function. Alternatively you can modify your code like this:

Auth.signup()
.then(function(a) {
    succCall()
    return loginSucc(a).then(null, loginErr);
}, errCall)

You can read more in these two SO question:

  1. Break promise chain
  2. Break Out of then promises in Angularjs

This also is a helpful read : Flattening Promise Chains

like image 58
gyosifov Avatar answered Sep 29 '22 13:09

gyosifov