Исключение, запущенное в обещании, не фиксируется в методе catch()

#javascript #exception #ecmascript-6 #es6-promise

Вопрос:

Я создаю исключение в асинхронном коде внутри Обещания. Исключение не фиксируется в catch() методе

 let x = new Promise((resolve,reject)=>{setTimeout(()=>{throw new Error(5);},3000)}).catch((error)=>{console.log(error)}) 

Вместо этого используйте этот код:

 let x = new Promise((resolve,reject)=>{setTimeout(()=>{reject( new Error(5));},3000)}).catch((error)=>{console.log(error)}) 

с Error помощью в reject ,перехватывается в методе catch ().
(Я выполнил код в консоли своего браузера и наблюдал за этим поведением)
Что это значит? Таким образом, если исключение запускается из JSON.parse() и выполняется попытка исключения, оно не будет захвачено? И если это так, то как я могу справиться с этой ситуацией? Я имею в виду эту ситуацию, в случае, JSON.parse() когда запускается исключение, потому что формат файла, возвращенного с сервера, неправильно отформатирован, как JSON.:

 function APIRequest(){
return new Promise((resolve,reject)=>{

let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
  if (xhr.readyState == 4) {
                if (xhr.status >= 200 amp;amp; xhr.status<299 || xhr.status == 304) {
                    let response = JSON.parse(xhr.responseText);
                    resolve(response);
                } else {
                    reject('something is gone wrong')
                }
}
xhr.open('GET','URL_REQUEST);
xhr.send(null);

});
} 

(Я знаю , что есть fetch() , это пример…)
Должен ли я использовать старый try-catch круг JSON.parse и в старом блоке catch ? reject(error) Или есть более чистое решение?

Комментарии:

1. Ошибка превращается в отклоненное обещание только в асинхронной функции.

2. @jonrsharpe Спасибо. Я не хочу использовать структуру асинхронного ожидания. Так я должен поступить в своем обратном вызове: try{JSON.parse().....other code} catch(e){reject(e)}

3. @jonrsharpe Если ошибка возникает синхронно , то она отклонит обещание: new Promise(() => { throw new Error() }) . Примечание для OP: вы должны вызвать reject функцию, чтобы отклонить обещание, а не выдавать ошибку.

4. Лично я бы сделал const delay = ms => new Promise(r => setTimeout(r, ms)); let x = delay(3000).then(()=>{ throw new Error(5); }).catch((error)=>{ console.log(error) }); так, чтобы ошибка синхронно выбрасывалась в обработчике обещаний.