6

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()
});
rooftop
  • 3,031
  • 1
  • 22
  • 33
  • This post might help you: http://stackoverflow.com/questions/12149993/attempting-to-break-jquery-promise-chain-with-then-fail-and-reject – Mathew Thompson Mar 20 '13 at 21:16
  • [This post](http://net.tutsplus.com/tutorials/javascript-ajax/wrangle-async-tasks-with-jquery-promises/) will help you understand promises better. In general if you want to use conditionals you should be saving the promise as a variable and executing your `then` `success` or `fail` inside your conditionals, you appear to be doing it the other way around. – acconrad Mar 20 '13 at 21:28

1 Answers1

4

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.

Beetroot-Beetroot
  • 18,022
  • 3
  • 37
  • 44