Я хотел бы использовать цепочку Promise для загрузки некоторых данных перед запуском приложения. Итак, у меня будет что-то вроде:
fetch('path/to/data.json')
.then((response) => response.json())
.then((data) => {
console.log('Hey cool, we're done w/ the promise chain here');
startApp(data);
})
.catch((error) => console.error('Error in promise chain: ${error}'));
Он работает, но с этой настройкой любые ошибки в моей функции startApp
(или любые последующие функции по линии) обрабатываются в цепочке Promise, что кажется неправильным.
Примеры обещаний, которые я нахожу, обычно заканчиваются консольным журналом в последнем then()
цепочки, поэтому они не очень поучительны в этом.
startApp
не находясь внутри цепочки? Вы всегда будете в цепочке обещаний. Однако вы можете легко отделить логику для обработки ошибок fetch
и ваших приложений, потребляющих данные, следующим образом:
fetch('path/to/data.json')
.then(response => response.json())
.then(startApp, handleFetchError)
.catch(error => console.error('Error from startApp or handleFetchError: ${error}'));
В соответствии с эффектами, наблюдаемыми в вопросе, реализация Promise вызывает обработчик .then
внутри блока try/catch
. Если ошибка поймана, обещание, возвращенное к тому then
, отклоняется по той же причине.
Чтобы сообщать об ошибках приложения отдельно, вы можете разместить свой собственный блок try/catch
вокруг приложения и явно обрабатывать отчет об ошибках. Если верхний уровень, then
обработчик возвращает без повторного метания ошибки, следующий catch
обработчик не вызываются.
НАПРИМЕР
fetch('path/to/data.json')
.then((response) => response.json())
.then((data) => {
console.log('Hey cool, we're done w/ the promise chain here');
try {
startApp(data);
}
catch( err) {
console.log( "An application error occurred:");
console.error( err);
}
// returning without re-throwing the error
})
.catch((error) => console.error('Error in promise chain: ${error}'));
Я также видел вызовы таймера, используемые для того, чтобы вызывать ошибки за пределами цепочки обещаний, чтобы не допустить их потребления в качестве обещаний. Не уверен, что трассировка стека адекватна, но, по крайней мере, она указывает, что произошла ошибка приложения:
НАПРИМЕР
fetch('path/to/data.json')
.then((response) => response.json())
.then((data) => {
console.log('Hey cool, we're done w/ the promise chain here');
try {
startApp(data);
}
catch( err) {
setTimeout( function () { throw err}, 0);
}
})
.catch((error) => console.error('Error in promise chain: ${error}'));
Другой способ - запустить приложение с помощью таймера, чтобы он не выполнялся в цепочке обещаний, чтобы начать с :-)
setTimeout(startApp, 0, data);
.finally()
также опция