首页 文章

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

提问于
浏览
6

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

我有一个名为doSomething()的函数,它可以执行一段时间,然后返回一个RSVP.Promise . 然后,在返回的promise中注册成功和失败回调链(请参阅下面的代码) . 我期望的行为是,如果承诺得到满足,那么在promise中注册的成功回调链将被触发,如果承诺被拒绝(失败),则将触发失败回调链 .

我得到了承诺履行时的预期行为,但是我得到的行为与承诺被拒绝时的预期不同 . 也就是说,成功回调被链接,并且一个成功回调的输出被传递到链中的下一个成功回调 . 但似乎失败的回调并没有被束缚 . 它们的行为几乎与try / catch块中的catch类似(请参阅下面的代码和输出) .

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

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
    );

**当履行承诺(成功)时,这是我得到和预期的输出:

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

**当承诺被拒绝(失败)时,这是我得到的输出:

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

**这是我的预期(在拒绝/失败的承诺上):

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

1 回答

  • 11

    你应该忘记 .then() 甚至需要多于1个参数并使用 .catch 方法,它会更有意义 .

    Promise提供了一些同步代码构造的对应关系,但是当你只有一个低级 .then() 时,这不是很明显 . 您正在寻找的基本上是一系列回调/回调聚合,但这根本不是承诺的重点 .

    想想 .catch(fn).then(null, fn) 相同:

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

    并行同步代码(想象 doSomething 同步返回):

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

    多次捕获(记住 .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
    });
    

    相似之处:

    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
    }
    

    所以现在您应该注意到您可以通过抛出而不是返回http://jsfiddle.net/VYSj7/3/来创建预期结果

    .catch() 是IMO提供承诺库的必备方法,并且将来也将包含在内置的Javascript承诺中 . 但是,如果这样的方法不是使用原型):

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

    另见rejection turns into fulfillment

相关问题