Почему бы родительскому обещанию не уловить отклонение вложенного обещания? - PullRequest
0 голосов
/ 04 апреля 2019

Почему вложенное отклоненное обещание не будет поймано родительским обещанием? Но, если я сделаю «бросок» внутри родительского обещания, его поймают.

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 ]

1 голос
/ 04 апреля 2019

У вас есть функция отклонения, rej, переданная в обратный вызов обещания. Вы должны использовать это, чтобы отклонить обещание, а не создавать новое отклоненное обещание. Вот для чего:

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);
});
1 голос
/ 04 апреля 2019

Вы не отвергаете родителя, вы только что создали новое вложенное отклоненное обещание, а затем сразу же выбросили его.

Вот как вы можете переписать это:

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. Отменить результат.

Даже при том, что здесь (создается) обещание создается, вы ничего не делаете с результатом. Это то же самое, что вызов функции, но затем ничего не делать с тем, что было 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');

});

Строка выполняется, но она «бессмысленна», поскольку не имеет побочных эффектов.

0 голосов
/ 04 апреля 2019

Promise.reject("A plain reject") возвращает Обещание, состояние которого отклонено, то есть обычный объект, а не выдаваемая ошибка.

Но вы ничего не делаете с Обещанием, возвращаемым из Promise.reject("A plain reject").И из-за этого нет никакого способа, которым Обещание, созданное new Promise((res, rej) => {}), могло бы знать, какое состояние имеет Обещание (например, что оно было отклонено), и даже если бы оно знало состояние, оно не знало бы, что оно должно что-то делатьс этим обещанием.Возможно, вы захотите сделать что-то еще с Promise.

С другой стороны, если вы throw допустили ошибку в new Promise((res, rej) => {}), это происходит немедленно, останавливает выполнение кода и запускается обработка ошибок.Обещание неявно ловит эту ошибку внутри, и ее состояние отклоняется.

...