Мы добавили обработчик события для "unhandledRejection" в нашем приложении узла, этот обработчик завершает процесс (как говорит узел, по умолчанию скоро ).
Однако мы видим то, что кажется лишним (или, по крайней мере, преждевременным) событиями.
Мы используем Q.allSettled
(который обрабатывает отклоненные обещания), я вижу в отладчике, что массив обещаний имеет два элемента: первый отклоненный ивторой в ожидании (будет разрешен ).После установки точек останова в обработчике unhandledRejection
и в then
после allSettled
я сначала получаю unhandledRejection
, а сразу после then
(так, обработано отклонение ).
Документация для unhandledRejection
гласит (выделено мое):
Событие 'unhandledRejection'
генерируется всякий раз, когда Promise
отклоняется и обработчик ошибок не присоединяется к обещанию в пределах цикла событий.
Я предполагаю, что механизм, который создал массив обещаний, заблокирован между отклонением первого обещания и созданием массива, но у меня нетНе удалось воспроизвести это на игрушечном примере.
Лучший минимальный пример, который мне удалось придумать, немного надуманный, но я думаю, что у него та же основная причина, что и у нашего кода.Я что-то здесь упускаю?Как узел может заставить unhandledRejection
завершить процесс по умолчанию, если это возможно?
process.on("unhandledRejection", (reason, p) => {
console.error(`### Got unhandled rejection: '${reason}'`);
});
function doesNotFireUnhandledRejection() {
let rejected = Promise.reject('an error');
return new Promise((resolve, reject) => {
resolve(rejected);
})
.catch(err => console.log("Caught:", err));
}
function firesUnhandledRejection() {
let rejected = Promise.reject('an error');
return new Promise((resolve, reject) => {
setTimeout(() => resolve(rejected), 0);
})
.catch(err => console.log("Caught:", err));
}
Кстати, то же самое происходит с setImmediate
, но не с process.nextTick
(хотя я мог поклясться, что на прошлой неделеprocess.nextTick
сделал причиной события ...).