简体   繁体   English

rsvp.js如何使用失败回调链处理被拒绝的承诺

[英]How rsvp.js handles rejected promise with chain of failure callbacks

Re: https://github.com/tildeio/rsvp.js 回复: https//github.com/tildeio/rsvp.js

I have a function called doSomething() that does something for a little while and then returns an RSVP.Promise. 我有一个名为doS​​omething()的函数,它可以执行一段时间,然后返回一个RSVP.Promise。 Then, a chain of success and failure callbacks are registered with the returned promise (see code below). 然后,在返回的promise中注册成功和失败回调链(请参阅下面的代码)。 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. 我期望的行为是,如果承诺得到满足,那么在promise中注册的成功回调链将被触发,如果承诺被拒绝(失败),则将触发失败回调链。

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). 它们的行为几乎与try / catch块中的catch类似(请参阅下面的代码和输出)。

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? 这是否真的是它的工作方式,或者这是rsvp.js处理拒绝/失败的承诺的方式中的错误,该承诺具有向其注册的一系列失败回调? 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. 我现在正在阅读Promises / A +规范以试图解决这个问题,但如果有人知道这些东西是他们的头脑,那么我很乐意听到您的解释。 Thanks in advance. 提前致谢。

jsfiddle: http://jsfiddle.net/rylie/VYSj7/2/ jsfiddle: http//jsfiddle.net/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    

You should just forget that .then() even takes more than 1 argument and use the .catch method and it will make more sense. 你应该忘记.then()甚至需要多于1个参数并使用.catch方法,它会更有意义。

Promises provide a correspondence to some sync code constructs but this isn't very visible when you just have a low-level .then() . Promise提供了一些同步代码构造的对应关系,但是当你只有一个低级别的.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) : .catch(fn)想象成.catch(fn) .then(null, fn)

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

Parallels the sync code (imagine doSomething returns synchronously): 并行同步代码(想象doSomething同步返回):

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) 多次捕获(记住.catch.catch .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.net/VYSj7/3/ 所以现在你应该注意到你可以通过投掷而不是返回http://jsfiddle.net/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. .catch()是IMO提供承诺库的必备方法,并且将来也将包含在内置的Javascript承诺中。 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 另见拒绝变为履行

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM