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

MrF*_*ion 3 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);
    }
);
Run Code Online (Sandbox Code Playgroud)

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

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


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

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

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

Ber*_*rgi 6

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

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

这是Chrome的错误吗?

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

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

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

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

    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);
    });
    
    Run Code Online (Sandbox Code Playgroud)
  • 或者重新抛出异常(类似于返回被拒绝的承诺):

    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);
    });
    
    Run Code Online (Sandbox Code Playgroud)


Ben*_*aum 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);
}
Run Code Online (Sandbox Code Playgroud)

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

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