Шаблон первой ошибки для ES7 Async / Await
Исправлять ошибки - это не весело. В этой статье я покажу вам схему работы с ошибками в Async / Await. Этот шаблон избегает использования try / catch.
// Callback fetch(URL, (error, response) => ...) // Promise fetch(URL).then((response) => ...).catch((error) => ...) // Async / await try { fetch(URL) } catch (error) {...}
Обратите внимание, что с помощью обратных вызовов у вас нет другого выбора, кроме как справиться с ошибкой или, по крайней мере, чувствовать себя виноватым, что не справились с ней.
Эта проблема
async fetchData() { let json; try { const response = await fetch(URL) try { json = await response.json() } catch (error) { console.log("Parsing failed", error) return } } catch (error) { console.log("Request failed", error) return } const stars = json.stargazers_count this.setState({stars}) }
Фу, я надеюсь, что вам это не нравится, как и мне, исключения должны быть исключительными, и в проблемах с подключением на мобильном устройстве нет ничего исключительного, это нормальный поток управления.
Перейти к заявлению, которое считается вредным - Эдсгер Дейкстра 1968
Я считаю, что try / catch - это прославленный оператор Go To, выполнение останавливается, а управление переходит к блоку catch. Его следует использовать с осторожностью для исключений, а не для нормального потока управления.
Итак, мы перешли от явного описания возвращаемых ошибок к выбрасыванию исключений, это не похоже на прогресс.
Возможное решение
async fetchData() { const [responseError, response] = await fetch(URL); if (responseError || !response) { console.log("Request failed", responseError) return } const [parseError, json] = await response.json() if (parseError || !json) { console.log("Request failed", parseError) return } const stars = json.stargazers_count this.setState({stars}) }
При этом используется деструктуризация массива, и, поскольку ошибка является первым значением, это заставляет задуматься об обработке ошибок. Я смешал обработку ошибок Go с обратными вызовами при первой ошибке NodeJS.
Детали реализации
const errorFirstPromise = (promise) => { return new Promise((resolve) => { return promise.then((result) => { return resolve([null, result]) }).catch((error) => { return resolve([error, null]) }) }) }
Если кто-то думает, что это хороший шаблон, я соберу узел узла. Пожалуйста, оставьте комментарий.
Обновление: я опубликовал модуль npm для этого шаблона: https://www.npmjs.com/package/error-first