Автор: Валентино Гальярди. Переводчик: Front-end Xiaozhi Источник: Валентиног
Ставь лайк и смотри, поиск в WeChat【Переезд в мир】Обратите внимание на этого человека, который не имеет большого фабричного прошлого, но имеет восходящий и позитивный настрой. эта статья
GitHub
GitHub.com/QQ449245884…Он был включен, статьи были классифицированы, и многие мои документы и учебные материалы были систематизированы.
Все говорили, что нет проекта для написания резюме, поэтому я помог вам найти проект, и это было с бонусом.【Учебник по строительству】.
Что такое ошибка в программировании
Наш процесс разработки не всегда был гладким парусом. Особенно в некоторых случаях мы можем захотеть остановить программу или уведомлять пользователя, когда происходит что-то плохое.
Например:
- Программа попыталась открыть несуществующий файл,
- сетевое соединение потеряно
- Пользователь ввел недопустимые символы
В таких случаях мы можем написать пользовательскую ошибку, чтобы управлять ею самостоятельно, или позволить движку определить эти ошибки для нас. Определив ошибку, мы можем уведомить пользователя сообщением или остановить выполнение исполнителя.
Что такое ошибка в JavaScript
JavaScript — объект ошибок. Чтобы создать ошибку в JS, вы можете использоватьError
объекта следующим образом:
const err = new Error('霍霍,好像哪里出问题了!')
также можно опуститьnew
Ключевые слова:
const err = Error('霍霍,好像哪里出问题了!')
Созданный объект ошибки имеет три свойства:
-
message: строка с сообщением об ошибке
-
name: неверный тип
-
stack: трассировка стека выполнения функции
Например, мы используемTypeError
объект создает ошибку, соответствующуюmessage
созданный номер входящего символа,name
да"TypeError"😀
const wrongType = TypeError("霍霍,好像哪里出问题了!")
wrongType.message // "霍霍,好像哪里出问题了!"
wrongType.name // "TypeError"
Многие типы ошибок в JavaScript
В JavaScript есть много типов ошибок 😱, например:
- Error
- EvalError
- InternalError
- RangeError
- ReferenceError
- SyntaxError
- TypeError
- URIError
Помните, что все эти типы ошибок являются фактическими конструкторами, предназначенными для возврата нового объекта ошибки.
В нашем коде мы в основном используемError
а такжеTypeError
Два наиболее распространенных типа для создания собственных объектов ошибок 😳.
В большинстве случаев большинство ошибок исходят непосредственно от движка JavaScript, например.InternalError
илиSyntaxError
.
Если вы переназнаетеconst
Когда переменная объявляется, она вызываетTypeError
ошибка.
const name = "前端小智"
name = "王大冶"
// // TypeError: Assignment to constant variable.
SyntaxError
Ошибка обычно связана с ошибкой в написании ключевого слова, например:
va x = '33';
// SyntaxError: Unexpected identifier
Или при создании ключевого слова в неправильном месте, например.await
а такжеasync
использование:
function wrong(){
await 99;
}
wrong();
// SyntaxError: await is only valid in async function
еще одинTypeError
Примером может служить манипулирование несуществующими элементами DOM на странице.
Uncaught TypeError: button is null
Помимо этих встроенных ошибок, в браузере присутствуют:
-
DOMException
-
DOMError, теперь устарела и больше не используется.
DOMException
представляет собой серию ошибок, связанных с веб-API. Они выбрасываются, когда мы делаем глупости в браузере, например:
document.body.appendChild(document.cloneNode(true));
результат:
Uncaught DOMException: Node.appendChild: May not add a Document as a child
Что такое исключение?
Большинство разработчиков считают ошибки и исключения одним и тем же. Фактически,Объекты ошибок становятся исключениями только тогда, когда они выброшены.
Чтобы создать исключение в JavaScript, мы используемthrow
Ключевое слово выдает ошибку:
const wrongType = TypeError("霍霍,好像哪里出问题了!")
throw wrongType;
Короткая форма:
throw TypeError("霍霍,好像哪里出问题了!")
или
throw new TypeError("霍霍,好像哪里出问题了!")
Выброс async вне тела функции или условия маловероятен, рассмотрим следующий пример:
function toUppercase(string) {
if (typeof string !== "string") {
throw TypeError("霍霍,好像哪里出问题了!");
}
return string.toUpperCase();
}
Здесь мы проверяем, являются ли параметры функции строками. Если нет, мы бросаем исключение. Технически, в JavaScript можно генерировать что угодно, а не только неправильные объекты.
throw Symbol();
throw 33;
throw "Error!";
throw null;
Тем не менее, лучше избегать этих вещей: правильная ошибка всегда брошена объектами, а не некоторые основные типы.
Это помогает обеспечить согласованность обработки ошибок в коде. Можно ожидать, что другие члены будут доступны для объекта ошибки.error.message
илиerror.stack
узнать источник ошибки.
Все говорили, что нет проекта для написания резюме, поэтому я помог вам найти проект, и это было с бонусом.【Учебник по строительству】.
Что происходит, когда мы выбрасываем исключение?
Исключения подобны поднимающемуся лифту: как только вы бросаете одно из них, оно всплывает вверх по стеку программы, если его где-нибудь не поймают.
Рассмотрим следующий код:
function toUppercase(string) {
if (typeof string !== "string") {
throw TypeError("参数类型需要是 string 的");
}
return string.toUpperCase();
}
toUppercase(4);
Запустите код, и вы увидите в консоли:
Uncaught TypeError: Wrong type given, expected a string
toUppercase http://localhost:5000/index.js:3
<anonymous> http://localhost:5000/index.js:9
Вы можете увидеть точную строку, где произошла ошибка.
Этот отчет представляет собой трассировку стека, которая помогает отслеживать проблемы в коде. Трассировка стека снизу вверх:
toUppercase http://localhost:5000/index.js:3
<anonymous> http://localhost:5000/index.js:9
В дополнение к просмотру этой трассировки стека в консоли браузера также можно передать объект ошибкиstack
свойства для просмотра.
Если исключение не перехвачено, то есть программист ничего не делает для его перехвата, программа рухнет.
Когда и где перехватывать исключения в вашем коде, зависит от конкретного варианта использования.
Например, мы можем захотеть передать исключение в стеке, чтобы полностью завершить работу программы. Это происходит, когда безопаснее позволить ошибке остановить программу, чем иметь дело с неверными данными.
Далее рассмотрим обработку ошибок и исключений в синхронном и асинхронном JavaScript.
Обработка ошибок при синхронизации
Синхронный код в большинстве случаев прост, поэтому его обработка ошибок также проста.
Обработка ошибок для обычных функций
Синхронный код выполняется в том же порядке, в котором он был написан. Давайте еще раз посмотрим на предыдущий пример:
function toUppercase(string) {
if (typeof string !== "string") {
throw TypeError("参数类型需要是 string 的");
}
return string.toUpperCase();
}
toUppercase(4);
Здесь движок вызывает и выполняетtoUppercase
. Все это происходит синхронно. Чтобы перехватывать исключения, генерируемые синхронными функциями, мы можем использоватьtry/catch/finally
:
try {
toUppercase(4);
} catch (error) {
console.error(error.message);
} finally {
}
try/catch/finally
является синхронной структурой, но она также может перехватывать исключения, возникающие асинхронно.
Используйте функции генератора для обработки ошибок
в JavaScript生成器函数
является специальной функцией. В дополнение к обеспечению двустороннего канала связи между его внутренней областью и его потребителями можно опциональноПаузаа такжевосстанавливаться.
Чтобы создать функцию генератора, мы используемfunction
поставить ключевое слово после*
:
function* generate() {
//
}
можно использовать внутри функцииyield
возвращаемое значение:
function* generate() {
yield 33;
yield 99;
}
Возвращаемое значение функции-генератораобъект итератора(объект итератора). Чтобы извлечь значение из генератора, мы можем использовать два метода:
- использовать
next()
метод - пройти через
for...of
траверс
Как показано ниже, чтобы получить значение в генераторе, мы можем сделать это:
function* generate() {
yield 33;
yield 99;
}
const go = generate();
const firstStep = go.next().value; // 33
const secondStep = go.next().value; // 99
Строители могут работать и по-другому: они могут получать значения и исключения, возвращаемые вызывающей стороной.
Кромеnext()
Кроме того, объект итератора, возвращенный генератором, имеетthrow()
метод. Используя этот подход, мы можем остановить программу, внедрив исключение в генератор
function* generate() {
yield 33;
yield 99;
}
const go = generate();
const firstStep = go.next().value; // 33
go.throw(Error("我要结束你!"));
const secondStep = go.next().value; // 这里会抛出异常
Чтобы получить эту ошибку, вы можете использовать в функции генератораtry/catch/finally
:
function* generate() {
try {
yield 33;
yield 99;
} catch (error) {
console.error(error.message);
}
}
В следующем примере используетсяfor...of
чтобы получить значение в функции генератора:
function* generate() {
yield 33;
yield 99;
throw Error("我要结束你!")
}
try {
for (const value of generate()) {
console.log(value)
}
} catch (error) {
console.log(error.message)
}
/* 输出:
33
99
我要结束你!
*/
Обработка ошибок в асинхронном режиме
JavaScript по своей сути является синхронным и однопоточным языком.
Среды хостинга, такие как движки браузера, используют множество веб-API, дополняя JS для взаимодействия с внешними системами и обработки операций, связанных с вводом-выводом.
К асинхронным операциям в браузере относятся: функции, связанные с таймером, события и обещания.
Обработка ошибок в асинхронном режиме отличается от синхронной обработки ошибок. Давайте посмотрим на некоторые примеры.
Все говорили, что нет проекта для написания резюме, поэтому я помог вам найти проект, и это было с бонусом.【Учебник по строительству】.
Обработка ошибок таймеров
Рассмотрим следующий фрагмент кода:
function failAfterOneSecond() {
setTimeout(() => {
throw Error("Something went wrong!");
}, 1000);
}
Эта функция выдает исключение примерно через 1 секунду, как правильно обработать это исключение?
Следующий метод не работает:
function failAfterOneSecond() {
setTimeout(() => {
throw Error("Something went wrong!");
}, 1000);
}
try {
failAfterOneSecond();
} catch (error) {
console.error(error.message);
}
мы знаемtry/catch
является синхронным, в то время какsetTimeout
является асинхронным. при выполнении кsetTimeout
При обратном вызове,try/catch
Он уже запущен, поэтому исключение не может быть перехвачено.
Они находятся на двух разных треках:
Track A: --> try/catch
Track B: --> setTimeout --> callback --> throw
Если вы можете запустить программу, поставьтеtry/catch
перейти кsetTimeout
в. Но такой подход не имеет особого смысла, и позже мы будем использовать промисы для решения подобных проблем.
Обработка ошибок в событиях
Операции событий DOM (прослушивание и запуск) определены вEventTarget
интерфейс.Element
узел,document
узел иwindow
Объекты имеют этот интерфейс. Кроме того, XMLHttpRequest,AudioNode
,AudioContext
Другие встроенные объекты браузера также используют этот интерфейс. Интерфейс состоит из трех методов,addEventListener
а такжеremoveEventListener
Используется для привязки и удаления функций прослушивателя,dispatchEvent
Используется для запуска событий.
Механизм обработки ошибок для событий DOM следует той же схеме, что и любой асинхронный веб-API.
Рассмотрим следующий пример:
const button = document.querySelector("button");
button.addEventListener("click", function() {
throw Error("Can't touch this button!");
});
Здесь исключение выдается сразу после нажатия кнопки. Как мы это поймаем? Следующий подход не имеет никакого эффекта и не предотвратит сбой программы:
const button = document.querySelector("button");
try {
button.addEventListener("click", function() {
throw Error("Can't touch this button!");
});
} catch (error) {
console.error(error.message);
}
а такжеsetTimeout
Такой же,addEventListener
Он также выполняется асинхронно.
Track A: --> try/catch
Track B: --> addEventListener --> callback --> throw
Если вы можете запустить программу, поставьтеtry/catch
перейти кaddEventListener
в. Но такой подход не имеет особого смысла, и позже мы будем использовать промисы для решения подобных проблем.
как насчет ошибки
Элементы HTML имеют множество обработчиков событий, таких какonclick
,onmouseenter
,onchange
подожди, конечноonerror
.
когдаimg
этикетка илиscript
Когда тег встречает несуществующий ресурс,onerror
Обработчики событий сработают.
Рассмотрим следующий пример:
...
<body>
<img src="nowhere-to-be-found.png" alt="So empty!">
</body>
...
Если файл не существует, консоль сообщит об ошибке:
GET http://localhost:5000/nowhere-to-be-found.png
[HTTP/1.1 404 Not Found 3ms]
В JS мы можем передатьonerror
чтобы поймать эту ошибку:
const image = document.querySelector("img");
image.onerror = function(event) {
console.log(event);
};
Лучший путь:
const image = document.querySelector("img");
image.addEventListener("error", function(event) {
console.log(event);
});
Этот метод полезен в некоторых случаях, когда запрошенный ресурс потерян, ноonerror
а такжеthrow
а такжеtry/cathc
Это не имеет значения.
Обработка ошибок с обещаниями
для демонстрацииPromise
Способ обработки, вернемся к делу в начале:
function toUppercase(string) {
if (typeof string !== "string") {
throw TypeError("Wrong type given, expected a string");
}
return string.toUpperCase();
}
toUppercase(4);
Генерировать исключение относительно просто, мы можем использоватьPromise.reject
а такжеPromise.resolve
:
function toUppercase(string) {
if (typeof string !== "string") {
return Promise.reject(TypeError("Wrong type given, expected a string"));
}
const result = string.toUpperCase();
return Promise.resolve(result);
}
из-за использованияPromise, так что вы можете использоватьthen
чтобы получить возвращенный контент или использоватьcatch
для отлова возникающих ошибок.
toUppercase(99)
.then(result => result)
.catch(error => console.error(error.message));
Результат вышеуказанного выполнения:
Wrong type given, expected a string
Кромеthen
а такжеcatch
, Обещание также имеетfinally
метод, аналогичныйtry/catch
серединаfinally
.
toUppercase(99)
.then(result => result)
.catch(error => console.error(error.message))
.finally(() => console.log("Run baby, run"));
Обещания, ошибки и броски
Использование Promise.reject может легко вызвать ошибки:
Promise.reject(TypeError("Wrong type given, expected a string"));
КромеPromise.reject
, мы также можем выйти из промиса, сгенерировав исключение.
Рассмотрим следующий пример:
Promise.resolve("A string").then(value => {
if (typeof value === "string") {
throw TypeError("Expected a number!");
}
});
Чтобы остановить распространение исключений, мы используем как обычноcatch
:
Promise.resolve("A string")
.then(value => {
if (typeof value === "string") {
throw TypeError("Expected a number!");
}
})
.catch(reason => console.log(reason.message));
Этот режим находится вfetch
Очень часто в:
fetch("https://example-dev/api/")
.then(response => {
if (!response.ok) {
throw Error(response.statusText);
}
return response.json();
})
.then(json => console.log(json));
можно использовать здесьcatch
Перехват исключений. Если мы потерпим неудачу или решим не перехватывать ее, исключение может свободно всплывать в стеке.
Использование промисов для обработки исключений в таймерах
Исключения, вызванные обратными вызовами, не могут быть перехвачены с помощью таймеров или событий.
function failAfterOneSecond() {
setTimeout(() => {
throw Error("Something went wrong!");
}, 1000);
}
// DOES NOT WORK
try {
failAfterOneSecond();
} catch (error) {
console.error(error.message);
}
Решение состоит в том, чтобы использовать промисы:
function failAfterOneSecond() {
return new Promise((_, reject) => {
setTimeout(() => {
reject(Error("Something went wrong!"));
}, 1000);
});
}
использоватьreject
, мы инициируем отклонение обещания с помощью объекта ошибки.
В этот момент мы можем использоватьcatch
Обработка исключений:
failAfterOneSecond().catch(reason => console.error(reason.message));
Используйте Promise.all для обработки ошибок
Promise.all(iterable)
Метод возвращает экземпляр Promise, который выполняет обратный вызов, когда все промисы в итерируемом параметре «разрешены» или когда параметр не содержит промиса;
const promise1 = Promise.resolve("All good!");
const promise2 = Promise.resolve("All good here too!");
Promise.all([promise1, promise2]).then((results) => console.log(results));
// [ 'All good!', 'All good here too!' ]
Если одно из промисов в аргументе терпит неудачу (отклоняется), этот обратный вызов экземпляра терпит неудачу (отклоняется), и причиной сбоя является результат первого невыполненного обещания.
const promise1 = Promise.resolve("All good!");
const promise2 = Promise.reject(Error("No good, sorry!"));
const promise3 = Promise.reject(Error("Bad day ..."));
Promise.all([promise1, promise2, promise3])
.then(results => console.log(results))
.catch(error => console.error(error.message));
// No good, sorry!
Так же независимо отPromise.all
Результат того, как запустить функцию,finally
будет выполнено:
Promise.all([promise1, promise2, promise3])
.then(results => console.log(results))
.catch(error => console.error(error.message))
.finally(() => console.log("Always runs!"));
Используйте Promise.any для обработки ошибок
Promise.any()
(Firefox > 79, Chrome > 85) Принимает итерацию объектов Promise и, пока одно из обещаний выполняется успешно, возвращает успешно выполненное обещание. Если ни одно из обещаний в итерируемом объекте не выполнено успешно (т. е. все обещания терпят неудачу/отклоняются), вернуть неудачныйpromise
а такжеAggregateError
экземпляр типа, которыйError
Подкласс , используемый для группировки одной ошибки. По существу, этот метод иPromise.all()
это наоборот.
const promise1 = Promise.reject(Error("No good, sorry!"));
const promise2 = Promise.reject(Error("Bad day ..."));
Promise.any([promise1, promise2])
.then(result => console.log(result))
.catch(error => console.error(error))
.finally(() => console.log("Always runs!"));
Здесь мы используемcatch
Обработка ошибок, вывод следующий:
AggregateError: No Promise in Promise.any was resolved
Always runs!
AggregateError
Объекты имеют одинаковые основныеError
те же свойства, плюсerrors
Атрибуты:
//
.catch(error => console.error(error.errors))
//
Это свойство созданоreject
массив каждой отдельной ошибки, произведенной
[Error: "No good, sorry!, Error: "Bad day ..."]
Используйте Promise.race для обработки ошибок
Promise.race(iterable)
Метод возвращает обещание, которое разрешается или отклоняется после разрешения или отклонения обещания в итераторе.
const promise1 = Promise.resolve("The first!");
const promise2 = Promise.resolve("The second!");
Promise.race([promise1, promise2]).then(result => console.log(result));
// The first!
Это показывает, что первое промис выполняется чаще, чем вторая строка. А как насчет ситуаций, связанных с отказом?
const promise1 = Promise.resolve("The first!");
const rejection = Promise.reject(Error("Ouch!"));
const promise2 = Promise.resolve("The second!");
Promise.race([promise1, rejection, promise2]).then(result =>
console.log(result)
);
// The first!
если поставитьreject
Как насчет первого?
const promise1 = Promise.resolve("The first!");
const rejection = Promise.reject(Error("Ouch!"));
const promise2 = Promise.resolve("The second!");
Promise.race([rejection, promise1, promise2])
.then(result => console.log(result))
.catch(error => console.error(error.message));
// Ouch!
Используйте Promise.allSettled для обработки ошибок
Promise.allSettled()
Метод возвращает обещание, которое былоfulfilled
илиrejected
После обещания с массивом объектов каждый объект представляет соответствующий результат обещания.
Рассмотрим следующий пример:
const promise1 = Promise.resolve("Good!");
const promise2 = Promise.reject(Error("No good, sorry!"));
Promise.allSettled([promise1, promise2])
.then(results => console.log(results))
.catch(error => console.error(error))
.finally(() => console.log("Always runs!"));
мы переходим кPromise.allSettled
Массив из двух промисов: одного разрешенного и одного отклоненного.
эта ситуацияcatch
не будет выполняться,finally
всегда будет выполняться.
[
{ status: 'fulfilled', value: 'Good!' },
{
status: 'rejected',
reason: Error: No good, sorry!
}
]
Используйте async/await для обработки ошибок
Для простоты используем предыдущую функцию синхронизацииtoUppercase
, и черезfunction
перед ключевым словомasync
чтобы преобразовать его в асинхронную функцию
async function toUppercase(string) {
if (typeof string !== "string") {
throw TypeError("Wrong type given, expected a string");
}
return string.toUpperCase();
}
Просто добавьте перед функциейasync
, функция возвращаетPromise
. Это означает, что мы можем сделать после вызова функцииthen
,catch
а такжеfinally
действовать
async function toUppercase(string) {
if (typeof string !== "string") {
throw TypeError("Wrong type given, expected a string");
}
return string.toUpperCase();
}
toUppercase("abc")
.then(result => console.log(result))
.catch(error => console.error(error.message))
.finally(() => console.log("Always runs!"));
когда изasync
Когда функция выдает исключение, мы можем использоватьcatch
захватить.
Самое главное, помимо этого способа, мы также можем использоватьtry/catch/finally
, как мы сделали с функцией синхронизации.
async function toUppercase(string) {
if (typeof string !== "string") {
throw TypeError("Wrong type given, expected a string");
}
return string.toUpperCase();
}
async function consumer() {
try {
await toUppercase(98);
} catch (error) {
console.error(error.message);
} finally {
console.log("Always runs!");
}
}
consumer();
выход:
Wrong type given, expected a string
Always runs!
Используйте асинхронные генераторы для обработки ошибок
в JavaScriptasync generators
— функция-генератор, способная создавать промисы вместо простых значений.
async function* asyncGenerator() {
yield 33;
yield 99;
throw Error("Something went wrong!"); // Promise.reject
}
На основе промисов здесь применяются те же правила для обработки ошибок. в асинхронном генератореthrow
вызовет обещаниеreject
, мы можем использоватьcatch
заблокировать его.
Чтобы использовать промисы с асинхронными генераторами, мы можем сделать это:
- затем метод
- Асинхронный обход
Из вышеизложенного мы знаем, что после двух вызововyield
После этого в следующий раз будет выброшено исключение:
const go = asyncGenerator();
go.next().then(value => console.log(value));
go.next().then(value => console.log(value));
go.next().catch(reason => console.error(reason.message));
Выходной результат:
{ value: 33, done: false }
{ value: 99, done: false }
Something went wrong!
Другой - использовать异步遍历
а такжеfor await...of
:
async function* asyncGenerator() {
yield 33;
yield 99;
throw Error("Something went wrong!"); // Promise.reject
}
async function consumer() {
for await (const value of asyncGenerator()) {
console.log(value);
}
}
consumer();
имеютasync/await
мы можем использоватьtry/catch
чтобы поймать исключение:
async function* asyncGenerator() {
yield 33;
yield 99;
throw Error("Something went wrong!"); // Promise.reject
}
async function consumer() {
try {
for await (const value of asyncGenerator()) {
console.log(value);
}
} catch (error) {
console.error(error.message);
}
}
consumer();
Выходной результат:
33
99
Something went wrong!
Объекты итераторов, возвращаемые функциями асинхронного генератора, также имеютthrow()
метод, очень похожий на его синхронный аналог. вызвать объект итератора здесьthrow()
Не вызовет исключение, но будет отклонен обещанием
async function* asyncGenerator() {
yield 33;
yield 99;
yield 11;
}
const go = asyncGenerator();
go.next().then(value => console.log(value));
go.next().then(value => console.log(value));
go.throw(Error("Let's reject!"));
go.next().then(value => console.log(value)); // value is undefined
Чтобы справиться с этой ситуацией извне, мы можем сделать:
go.throw(Error("Let's reject!")).catch(reason => console.error(reason.message));
Обработка ошибок в узле
Синхронная обработка ошибок в узле
Синхронная обработка ошибок в Node.js не сильно отличается от того, что мы видели до сих пор. Для синхронизации используйтеtry/catch/finally
Это будет работать просто отлично.
Асинхронная обработка ошибок в Node.js: шаблон обратного вызова
Для асинхронного кода Node.js в основном использует эти два метода:
- режим обратного вызова
- event emitters
В режиме обратного вызова асинхронный API Node.js принимает функцию, которая обрабатывается в цикле событий и выполняется, как только стек вызовов становится пустым.
Рассмотрим следующий код:
const { readFile } = require("fs");
function readDataset(path) {
readFile(path, { encoding: "utf8" }, function(error, data) {
if (error) console.error(error);
// do stuff with the data
});
}
Мы видим, что способ обработки ошибок здесь заключается в использовании обратных вызовов:
//
function(error, data) {
if (error) console.error(error);
// do stuff with the data
}
//
При использованииfs.readFile
Любая ошибка, вызванная чтением данного пути, мы получим объект ошибки.
На данный момент мы можем:
- Просто введите ошибку объекта
- бросить ошибку
- Передать ошибку другому обратному вызову
мы можем бросить исключение
const { readFile } = require("fs");
function readDataset(path) {
readFile(path, { encoding: "utf8" }, function(error, data) {
if (error) throw Error(error.message);
// do stuff with the data
});
}
Однако, как и события и таймеры в DOM, это исключение приведет к сбою программы. пройти черезtry/catch
Поймать не получается:
const { readFile } = require("fs");
function readDataset(path) {
readFile(path, { encoding: "utf8" }, function(error, data) {
if (error) throw Error(error.message);
// do stuff with the data
});
}
try {
readDataset("not-here.txt");
} catch (error) {
console.error(error.message);
}
Передача ошибки другому обратному вызову является предпочтительным методом, если мы не хотим сбой программы:
const { readFile } = require("fs");
function readDataset(path) {
readFile(path, { encoding: "utf8" }, function(error, data) {
if (error) return errorHandler(error);
// do stuff with the data
});
}
здесьerrorHandler
Как следует из названия, простая функция для обработки ошибок:
function errorHandler(error) {
console.error(error.message);
// do something with the error:
// - write to a log.
// - send to an external logger.
}
Асинхронная обработка ошибок в Node.js: генераторы событий
Большая часть работы, выполняемой в Node.js, основана намероприятиеиз. в большинстве случаев,emitter objectВзаимодействуйте с некоторыми наблюдателями, чтобы слушать сообщения.
Любой управляемый событиями модуль в Node.js (например, net) расширяет файл с именемEventEmitter
корневой класс.
в Node.jsEventEmitterСуществует два основных метода:on
а такжеemit
.
Рассмотрим следующий простой HTTP-сервер:
const net = require("net");
const server = net.createServer().listen(8081, "127.0.0.1");
server.on("listening", function () {
console.log("Server listening!");
});
server.on("connection", function (socket) {
console.log("Client connected!");
socket.end("Hello client!");
});
Здесь мы слушаем два события:listening
а такжеconnection
. В дополнение к этим событиям генераторы событий предоставляютerror
событие в случае возникновения ошибки.
Если вы запустите этот код на порту 80 вместо прослушивания предыдущего примера, вы получите исключение:
const net = require("net");
const server = net.createServer().listen(80, "127.0.0.1");
server.on("listening", function () {
console.log("Server listening!");
});
server.on("connection", function (socket) {
console.log("Client connected!");
socket.end("Hello client!");
});
выход:
events.js:291
throw er; // Unhandled 'error' event
^
Error: listen EACCES: permission denied 127.0.0.1:80
Emitted 'error' event on Server instance at: ...
Чтобы поймать его, мы можем зарегистрироватьerror
Обработчик события:
server.on("error", function(error) {
console.error(error.message);
});
Выходной результат:
listen EACCES: permission denied 127.0.0.1:80
Суммировать
В этом руководстве мы рассмотрели все виды обработки ошибок в JavaScript, от простого синхронного кода до расширенного асинхронного кода. В программе JavaScript исключения можно перехватывать несколькими способами.
Исключения в синхронном коде легче всего поймать. И наоборот, исключения в асинхронном режиме требуют некоторых трюков для обработки.
Новые API-интерфейсы JavaScript в браузерах почти всегда ориентированы наPromise
.then/catch/finally
илиtry/catch
режим дляasync/await
Обработка исключений становится проще.
общаться с
Статьи постоянно обновляются каждую неделю, и их можно искать в WeChat.【Переезд в мир】Сначала прочитай, ответь【Благосостояние】Вас ждет много фронтенд-видео, эта статья GitHubGitHub.com/QQ449245884…Он был записан, добро пожаловать в Star.