Handling branches with Promises

asynchronous, javascript, jquery, promise

Solution

This becomes easier by taking the view that `options.onSuccess(rc);` is executed unconditionally in the second `.then()` but never in the first.

Thus, the first `.then()` must pass on `rc` either :

- if `rc === 0`, in response to `storage.write(c)` completing

- or immediately if `rc !== 0`.

`.then()` is really handy for this because it naturally allows either a value of a new Promise to be returned from its `done` callback.

storage.provision(c).then(function(rc) {
    if(rc === 0) {
        var dfrd = $.Deferred();
        storage.write(c).done(function() {
            dfrd.resolve(rc);
        }).fail(dfrd.fail);
        return dfrd.promise();
    } else {
        return rc;//pass on rc to the second .then()
    }
}).then(function(rc){
    options.onSuccess(rc);
}).fail(function(e){
    //handle error using .reject()
});

I'm sure other approaches exist but this is the closest I can think of to your original concept.

It would be nice not to have to create a new Deferred when `rc === 0` but it's the most realistic approach to passing on `rc`, avoiding the need to modify `storage.write()` to behave in this way.

Problem

I have a problem with jQuery 1.9.1 promises, where I potentially need conditional logic that will return another deferred and I'm not sure how to handle it. This was my best attempt, but as the comments indicate below, when I hit the else branch, I still hit the second .then() function, where I'm hoping I could go back to the user. Any patterns for how to handle such a scenario? ``` storage.provision(c) .then(function(rc){ if(rc === 0){ storage.write(c); }else{ return options.onSuccess(rc); //how i got back to the users callbacks/promise, but this //takes me to the .then below } }) //storage.write returns a promise as well, do I do another .then // like this? .then(function(rc){ //I was hoping this would catch, the storage.write() case, and it does, but it also catches //the retun options.onSuccess(rc) in the else case. options.onSuccess(rc); }) .fail(function(e){ //handle error using .reject() }); ```

Original source

Related problems