承诺的第二个。然后()没有失败

时间:2014-05-29 21:29:37

标签: javascript google-chrome promise

我在链接.then()来电承诺时遇到了麻烦。执行以下代码时:

var prom = new Promise(function(resolve, reject) {
  //let's always fail
  reject(Error("buuuu!"));
});

var thenable = 
prom.then(
    function(done) {
        console.log("First handler: Done!: Argument: ", done);
        return "First then: DONE";
    },
    function(fail) {
        console.error("First handler: Fail!. Argument: ", fail);
        return "First then: FAIL";
    }
).then(
    function(done) {
        console.info("Second handler: Done!.  Argument: ", done);
    },
    function(fail) {
        console.error("Second handler: Fail!.  Argument: ", fail);
    }
);

这将在控制台中打印以下内容:

First handler: Fail!. Argument:  Error {stack: (...), message: "buuuu!"}
Second handler: Done!.  Argument:  First then: FAIL


为什么第二个then()调用了done处理程序而不是fail处理程序?

这是Chrome的错误吗? (请注意,我只对Google Chrome的行为感兴趣)

我是否需要从.then处理程序返回预先解析/拒绝的承诺?

2 个答案:

答案 0 :(得分:6)

  

为什么第二个then()调用了done处理程序而不是失败的处理程序?

因为你已经在链的第一个then()中处理了错误,所以使用从它返回的"First then: FAIL"字符串解析promise。

  

这是Chrome的错误吗?

不,这就是承诺应该如何运作。

  

我是否需要从.then处理程序返回预先解析/拒绝的Promise?

你可以这样做,是的。触发第二个失败处理程序的其他方法是:

  • 只需省略第一个错误处理程序:

    prom.then(function(done) {
        console.log("First handler: Done!: Argument: ", done);
        return "First then: DONE";
    }).then(function(done) {
        console.info("Second handler: Done!.  Argument: ", done);
    }, function(fail) {
        console.error("Second handler: Fail!.  Argument: ", fail);
    });
    
  • 或者重新抛出异常(类似于返回被拒绝的承诺):

    prom.then(function(done) {
        console.log("First handler: Done!: Argument: ", done);
        return "First then: DONE";
    }, function(fail) {
        console.error("First handler: Fail!. Argument: ", fail);
        throw new Error("First then: FAIL"); // or: throw fail;
        // alternatively, you can return a rejected promise:
        return Promise.reject(new Error("First then: FAIL"));
    }).then(function(done) {
        console.info("Second handler: Done!.  Argument: ", done);
    }, function(fail) {
        console.error("Second handler: Fail!.  Argument: ", fail);
    });
    

答案 1 :(得分:6)

  

为什么第二个then()调用了done处理程序而不是失败的处理程序?

让我们看一下代码在同步世界中的表现:

var value;
try{
    try {
        throw new Error("buuu!");
        console.log("First handler: Done!: Argument: ");
        value = "First then: DONE";
    } catch(e){
        console.error("First handler: Fail!. Argument: ", e);
        value = "First then: FAIL";
    }
    console.info("Second handler: Done!.  Argument: ", value);
}catch(e){
    console.error("Second handler: Fail!.  Argument: ", e);
}

当您处理catch子句中的错误时,就像处理then子句中的错误一样,您从中恢复。承诺示例与我们的同步示例完全相同。

如果您想表示您已执行恢复逻辑,但链上仍处于拒绝状态,请重新抛出。这就是它总是在同步代码中完成的。