Обещание reject() вызывает предупреждение "Нечистить (в обещании)"

После вызова обратного вызова обещания reject() в консоли Chrome появляется предупреждающее сообщение "Uncaught (in обещание)". Я не могу обернуть голову ни вокруг причины этого, ни как от него избавиться.

var p = new Promise((resolve, reject) => {
  setTimeout(() => {
    var isItFulfilled = false
    isItFulfilled ? resolve('!Resolved') : reject('!Rejected')
  }, 1000)  
})

p.then(result => console.log(result))
p.catch(error => console.log(error))

Внимание:

enter image description here

Изменить:

Я обнаружил, что если обработчик onRejected явно не предоставлен методу .then(onResolved, onRejected), JS автоматически предоставит неявный. Это выглядит так: (err) => throw err. Сгенерированный автоматически обработчик выдаст свою очередь.

Справка:

Если IsCallable (onRejected) 'равен false, то
     Пусть onRejected будет "Thrower".

http://www.ecma-international.org/ecma-262/6.0/index.html#sec-performpromisethen

Ответ 1

Это происходит потому, что вы не присоединяете обработчик перехвата к обещанию, возвращенному первым методом then, который поэтому не имеет обработчика, когда обещание отклоняется. У вас есть одно для обещания p в последней строке, но не для связанного обещания, возвращенного методом then, в строке перед ним.

Как вы правильно добавили в комментариях ниже, когда обработчик перехвата не предусмотрен (или он не является функцией), по умолчанию выдаст ошибку. В цепочке обещаний эту ошибку можно отследить с помощью обратного вызова метода catch, но если его там нет, обработчик JavaScript будет обрабатывать ошибку, как и любую другую неперехваченную ошибку, и применять обработчик по умолчанию в таких обстоятельствах, что приводит к выводу, который вы видите в консоли.

Чтобы избежать этого, привяжите метод .catch к обещанию, возвращенному первым then, следующим образом:

p.then( result =>  console.log('Fulfilled'))
 .catch( error =>  console.log(error) );

Ответ 2

Даже если вы правильно используете Promises: p.then(p1).catch(p2) вы все равно можете получить неперехваченное исключение, если ваша функция p2 в конечном итоге выдает исключение, которое вы намереваетесь перехватить, используя механизм, подобный window.onerror. Причина в том, что стек уже размотан обработкой ошибок, выполненной в обещании. Чтобы это исправить, убедитесь, что ваш код ошибки (вызываемый функцией reject) не вызывает исключение. Он должен просто вернуться.

Было бы неплохо, если бы код обработки ошибок мог обнаружить, что стек уже размотан (поэтому ваш вызов ошибки не должен иметь флаг для этого случая), и если кто-нибудь знает, как это легко сделать, я отредактирую этот ответ для включите это объяснение.