Uncaught (in promise) ... 使用 catch 时

Uncaught (in promise) ... when using catch

为什么下面的代码在被捕获的时候会报Uncaught (in promise) rejected错误?

function Test() {
  this.start = function(action) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        if (action == "fail") return reject("rejected");
        resolve("resolved");
      }, 1000);
    });
  }
}

const test = new Test();
const promise = test.start("fail");
promise.then(console.log);
promise.catch(console.error);

输出(在浏览器中)是:

rejected 来自 catch()

Uncaught (in promise) rejected 从调用到 reject

您的代码如下:

const test = new Test();
const promise = test.start("fail");

您创建一个承诺并提供一个字符串参数(“失败”)。

promise.then(console.log);
promise.catch(console.error);

你抓住了承诺并显示了错误

if (action == "fail") return reject("rejected");

您 return 带有字符串参数“rejected”的拒绝函数。

希望对您有所帮助。

这是更正后的代码:

function Test() {
  this.start = function(action) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        if (action == "fail") return reject(new Error("rejected"));
        resolve("resolved");
      }, 1000);
    });
  }
}

const test = new Test();
const promise = test.start("fail");
promise.then(console.log).catch(console.error);

你需要链接 .then() 和 .catch() 才能工作,

因为 .then() 将 return 一个新的 promise,而正是这个 promise 会抛出您需要捕获的错误

因为没有为您的 .then 做出任何承诺

要么将函数调用更改为

promise.then(console.log).catch(console.error);

或 将你的拒绝变成决心兑现你的承诺

function Test() {
    this.start = function(action) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                if (action == "fail") return resolve("rejected");
                return resolve("resolved");
            }, 1000);
        });
    }
}

希望这对您有所帮助

您正在分叉您的承诺链:

promise ---> .then( .. ) ---> ???
        \
         \
          +-> .catch( .. )

拒绝被 .catch 很好地捕获,但它 通过 .then 分支。这两个分支都是独立解决的。而且你没有在 .then 分支上捕获拒绝,导致未捕获的拒绝错误。

比较:

promise.then(console.log).catch(console.error)

链条如下所示:

promise ---> .then( .. ) ---> .catch( .. )

拒绝将跳过 .then 处理程序并转到最近的.catch

好的。答案很明显,但很容易错过。

.then(...) returns 又一个承诺。因此,您必须将 .catch(...) 附加到那个。

解决方案:

const promise = test.start("fail");
promise.then(console.log).catch(console.error);  

或更明确地说:

const promise = test.start("fail");
const promise2 = promise.then(console.log);
promise2.catch(console.error);

@deceze的answer/explaination还不错