最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How rsvp.js handles rejected promise with chain of failure callbacks - Stack Overflow

programmeradmin1浏览0评论

Re: .js

I have a function called doSomething() that does something for a little while and then returns an RSVP.Promise. Then, a chain of success and failure callbacks are registered with the returned promise (see code below). The behavior I expected was, if the promise is fulfilled, the chain of success callbacks registered with the promise will be fired, and if the promise is rejected (fails), the chain of failure callbacks will be fired.

I get the expected behavior for when the promise is fulfilled, but I get a behavior different than what I expected when the promise is rejected. That is, the success callbacks are chained and output of one success callback is passed on to the next success callback in the chain. But it appears the failure callbacks are not chained. They behave almost like the catch in a try/catch block (see code and output below).

Can someone explain this behavior? Is this really the way it's suppose to work, or is this an error in the way rsvp.js handles a rejected/failed promise that has a chain of failure callbacks registered with it? I'm reading the Promises/A+ spec now to try and figure this out, but if someone knows this stuff off the top of their head, would love to hear your explanation. Thanks in advance.

jsfiddle: /

doSomething()  // returns an RSVP.Promise object
    .then(
        function(message) { console.log("then success 1: " + message); return "from success 1"; },  // success callback
        function(message) { console.log("then failure 1: " + message); return "from failure 1"; }   // failure callback
    )
    .then(
        function(message) { console.log("then success 2: " + message); return "from success 2"; },  // success callback
        function(message) { console.log("then failure 2: " + message); return "from failure 2"; }   // failure callback
    )
    .then(
        function(message) { console.log("then success 3: " + message); return "from success 3"; }   // success callback
    )
    .then(
        null,
        function(message) { console.log("then failure 4: " + message); return "from failure 4"; }   // failure callback
    )
    .then(
        function(message) { console.log("then success 5: " + message); return "from success 5"; },  // success callback
        function(message) { console.log("then failure 5: " + message); return "from failure 5"; }   // failure callback
    );

** When the promise is fulfilled (succeeds), this is the output I get and expected:

then success 1: Promise fulfilled!
then success 2: from success 1
then success 3: from success 2
then success 5: from success 3 

** When the promise is rejected (fails), this is the output I get:

then failure 1: Promise rejected!
then success 2: from failure 1
then success 3: from success 2
then success 5: from success 3 

** This is what I expected (on a rejected/failed promise):

then failure 1: Promise rejected!
then failure 2: from failure 1
then failure 4: from failure 2
then failure 5: from failure 4    

Re: https://github./tildeio/rsvp.js

I have a function called doSomething() that does something for a little while and then returns an RSVP.Promise. Then, a chain of success and failure callbacks are registered with the returned promise (see code below). The behavior I expected was, if the promise is fulfilled, the chain of success callbacks registered with the promise will be fired, and if the promise is rejected (fails), the chain of failure callbacks will be fired.

I get the expected behavior for when the promise is fulfilled, but I get a behavior different than what I expected when the promise is rejected. That is, the success callbacks are chained and output of one success callback is passed on to the next success callback in the chain. But it appears the failure callbacks are not chained. They behave almost like the catch in a try/catch block (see code and output below).

Can someone explain this behavior? Is this really the way it's suppose to work, or is this an error in the way rsvp.js handles a rejected/failed promise that has a chain of failure callbacks registered with it? I'm reading the Promises/A+ spec now to try and figure this out, but if someone knows this stuff off the top of their head, would love to hear your explanation. Thanks in advance.

jsfiddle: http://jsfiddle/rylie/VYSj7/2/

doSomething()  // returns an RSVP.Promise object
    .then(
        function(message) { console.log("then success 1: " + message); return "from success 1"; },  // success callback
        function(message) { console.log("then failure 1: " + message); return "from failure 1"; }   // failure callback
    )
    .then(
        function(message) { console.log("then success 2: " + message); return "from success 2"; },  // success callback
        function(message) { console.log("then failure 2: " + message); return "from failure 2"; }   // failure callback
    )
    .then(
        function(message) { console.log("then success 3: " + message); return "from success 3"; }   // success callback
    )
    .then(
        null,
        function(message) { console.log("then failure 4: " + message); return "from failure 4"; }   // failure callback
    )
    .then(
        function(message) { console.log("then success 5: " + message); return "from success 5"; },  // success callback
        function(message) { console.log("then failure 5: " + message); return "from failure 5"; }   // failure callback
    );

** When the promise is fulfilled (succeeds), this is the output I get and expected:

then success 1: Promise fulfilled!
then success 2: from success 1
then success 3: from success 2
then success 5: from success 3 

** When the promise is rejected (fails), this is the output I get:

then failure 1: Promise rejected!
then success 2: from failure 1
then success 3: from success 2
then success 5: from success 3 

** This is what I expected (on a rejected/failed promise):

then failure 1: Promise rejected!
then failure 2: from failure 1
then failure 4: from failure 2
then failure 5: from failure 4    
Share Improve this question edited Oct 30, 2013 at 22:29 RBR asked Oct 30, 2013 at 20:39 RBRRBR 9993 gold badges13 silver badges24 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 12

You should just forget that .then() even takes more than 1 argument and use the .catch method and it will make more sense.

Promises provide a correspondence to some sync code constructs but this isn't very visible when you just have a low-level .then(). What you are looking for is basically an array of callbacks/callback aggregation but that is not the point of promises at all.

Think of .catch(fn) same as .then(null, fn):

doSomething().then(function(val) {
    console.log(val);
}).catch(function(e) {
    console.error(e);
});

Parallels the sync code (imagine doSomething returns synchronously):

try {
    var val = doSomething();
    console.log(val);
}
catch(e) {
    console.error(e);
}

Multiple catches (remember that .catch is more readable alias to .then(null, fn)

doSomething().then(function(val) {
    console.log(val);
}).catch(function(e) {
    return e;
}).catch(function(e){
    //Will not get here ever
    //because error thrown from doSomething()
    //was handled in the upper catch which doesn't trow
});

Parallels:

try {
    try {
        var val = doSomething();
        console.log(val);
    }
    catch(e) {
        //no need for explicit return e
    }
}
catch( e ) {
    //Will not get here ever
    //because error thrown from doSomething()
    //was handled in the upper catch which doesn't trow
}

So now you should notice that you can create the expected result by throwing instead of returning http://jsfiddle/VYSj7/3/

.catch() is IMO an essential method for a promise library to provide and will also be included in the built-in Javascript promises in future. However, if such method isn't provided, you can (or should be, unfortunately there are implementations that don't use prototypes):

Promise.prototype.catch = function(fn) {
    return this.then(null, fn);
};

See also rejection turns into fulfillment

发布评论

评论列表(0)

  1. 暂无评论