为何父母的诺言不能赶上嵌套的诺言的拒绝?

时间:2019-04-04 16:49:44

标签: javascript node.js promise es6-promise

为什么嵌套的拒绝承诺不会被父承诺捕获?但是,如果我在父母承诺中做出“抛掷”,就会被抓住。

var parent = new Promise((res, rej) => {
    // this DOES NOT get caught by the parent. 
    Promise.reject("A plain reject");

    // this gets caught by the parent
    // throw new Error("Arbitrary  error");
});

parent.catch(err => {
    console.log("parent catches the error");
});

更新:我不打算在父母抓住被拒绝的承诺的地方重写它。我只想了解“为什么”?谢谢!

3 个答案:

答案 0 :(得分:1)

您不是拒绝父母,您只是创建了一个新的嵌套拒绝承诺,然后立即将其丢弃。

这是您可以重写的方式:

const parent = new Promise((res, rej) => {
    // nested reject
    Promise.reject("A plain reject").then(res, rej);
});

这仍然是一个糟糕的模式。如果可以的话,您应该真正避免使用new Promise。在不看到更实际的示例的情况下,很难告诉您如何正确地编写它,因为上面的内容可以重写为:

const parent = Promise.reject("A plain reject");

编辑对后续操作的回复:

更新:我不打算在父母抓住被拒绝的承诺的地方重写它。我只想了解“为什么”?谢谢!

当您throw发生异常时,它是一种语言功能,它将停止当前函数并冒泡该异常,直到调用堆栈中的某个内容具有catch

当您编写如下语句时:

Promise.reject('foo');

您:

  1. 调用reject()对象上的Promise函数。
  2. 丢弃结果。

即使在这里创建了(拒绝的)promise,您对结果也不做任何事情。这与调用函数完全相同,但是随后对returned所做的事情不做任何事情,并想知道结果在哪里。

第一个例子:

var parent = new Promise((res, rej) => {
    // this DOES NOT get caught by the parent. 
    Promise.reject("A plain reject");

    // this gets caught by the parent
    // throw new Error("Arbitrary  error");
});

实际上与以下内容相同:

var parent = new Promise((res, rej) => {
    // this DOES NOT get caught by the parent. 
    true;

});

var parent = new Promise((res, rej) => {
    // this DOES NOT get caught by the parent. 
    5;

});

var parent = new Promise((res, rej) => {
    // this DOES NOT get caught by the parent. 
    "hello".indexOf('h');

});

该行被执行了,但是因为没有副作用,所以它是“无意义的”。

答案 1 :(得分:1)

您有一个拒绝函数rej,已传递给promise回调。您应该使用它来拒绝承诺,而不是创建新的被拒绝的Promise。这就是它的用途:

var parent = new Promise((res, rej) => {
    // nested reject
    rej("A plain reject");
});

parent.catch(err => {
    console.log("parent catches the error: ", err);
});

如果由于某种原因您已经不能兑现承诺,则可以解决该问题,这也会引发麻烦,尽管情况似乎很奇怪:

var parent = new Promise((res, rej) => {
    // nested reject
    res(Promise.reject("A plain reject"));
});

parent.catch(err => {
    console.log("parent catches the error", err);
});

答案 2 :(得分:0)

Promise.reject("A plain reject")返回一个Promise,该Promise的状态被拒绝,这只是一个常规Object,而不是抛出的错误。

但是您不会对Promise.reject("A plain reject")返回的Promise进行任何操作。因此,new Promise((res, rej) => {})创建的Promise不可能知道Promise的状态(例如,它被拒绝了),即使知道该状态,也不会知道它应该用那个承诺做点事。您可能想对Promise做其他事情。

反之,如果您在thrownew Promise((res, rej) => {})内发生错误,则会立即发生,停止代码执行,并开始错误处理。 Promise隐式捕获了该错误,并且错误状态被拒绝。