Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Непонятный Unhandled promise rejection (https://javascript.ru/forum/misc/70142-neponyatnyjj-unhandled-promise-rejection.html)

tilin 14.08.2017 17:01

Непонятный Unhandled promise rejection
 
Немогу понять, почему поведение разное.

В таком варианте все работает, как ожидалось:
const debug = require("debug")("m");

const promise = new Promise((resolve, reject) => {
	setTimeout(() => {
		reject("promise rejected");
	}, 1000);
});

promise.then(
	v => {
		debug("resolve", v);
	},
	e => {
		debug("reject", e);
	},
);

Ставлю catch вместо обработчика reject
const debug = require("debug")("m");

const promise = new Promise((resolve, reject) => {
	setTimeout(() => {
		reject("promise rejected");
	}, 1000);
});

promise.then(v => {
	debug("resolve", v);
});

promise.catch(e => {
	debug("catch: ", e);
	return;
})


работает так же, но nodejs кричит UnhandledPromiseRejectionWarning. Как понимать этот варнинг?

Alexandroppolus 14.08.2017 17:46

Цитата:

Сообщение от tilin (Сообщение 461637)
Ставлю catch вместо обработчика reject
const debug = require("debug")("m");

const promise = new Promise((resolve, reject) => {
	setTimeout(() => {
		reject("promise rejected");
	}, 1000);
});

promise.then(v => {
	debug("resolve", v);
});

promise.catch(e => {
	debug("catch: ", e);
	return;
})


работает так же, но nodejs кричит UnhandledPromiseRejectionWarning. Как понимать этот варнинг?

На самом деле then здесь неявно получает второй параметр, и полностью выглядит так:
promise.then(v => {
	debug("resolve", v);
},
e => {
        throw e;
});


в итоге промис, созданный этим then, будет отклоненный. Именно он и вываливает ошибку, т.к. для него нет вызова then или catch (тот catch, который идет далее, вызывается на исходном промисе).

А в первом случае в then вторым аргументом попадала функция, которая не реджектила, в итоге then возвращал зарезолвленный промис.

tilin 14.08.2017 20:56

Круто.

Т.е. если промис может реджектиться, то надо, либо then делать с двумя параметрами, либо далеть цепочку then...catch, чтобы отловить отклоненные промисы, возвращенные этими 'неявными' функциями (кстати, отсутствие onFulfilled функции в then в такой же ситуации никаких варнингов не вызывает).

А где в стандарте описана эта ситуация с неявной подстановкой второго параметра, никак не могу найти.

Alexandroppolus 21.08.2017 11:18

Цитата:

Сообщение от tilin (Сообщение 461647)
А где в стандарте описана эта ситуация с неявной подстановкой второго параметра, никак не могу найти.

правильнее сказать: "должно работать, как если бы на месте отсутствующей функции была функция e => throw e". Аналогичное, кстати, справедливо и для первого параметра then - там подставляется e => e

Это скорее "возможная реализация". В стандарте о заменах не упоминается, но указано, что должно получиться в итоге. https://promisesaplus.com/ пп. 2.2.7.3 и 2.2.7.4, что достигается, например, при таких заменах.


Часовой пояс GMT +3, время: 21:37.