Переводчик пресса:использовать.catch()
поймать все исключения
- оригинал:Async Await Error Handling in JavaScript
- Переводчик:Fundebug
В этой статье используется свободный перевод, и авторские права принадлежат оригинальному автору.
Обработка исключений в async/await сбивает с толку. Хотя есть много способов справиться сИсключения для асинхронных функций, но даже опытные разработчики иногда ошибаются.
Предположим, у вас есть файл с именемrun()
асинхронная функция. В этой статье я опишу 3 способа борьбы сrun()
исключение:try/catch
, Языковой стиль Go, используется при вызове функцииcatch()
(которыйrun().catch()
). Я объясню вам, почему это на самом деле все, что вам нужноcatch()
достаточно.
try/catch
когда вы впервые используетеasync/await
, вы можете попробовать использоватьtry/catch
Окружите каждую асинхронную операцию. если выawait
Отклоненный Promise, JavaScript выдает уловимую ошибку.
run();
async function run() {
try {
await Promise.reject(new Error("Oops!"));
} catch (error) {
error.message; // "Oops!"
}
}
try/catch
Способен перехватывать неасинхронные исключения.
run();
async function run() {
const v = null;
try {
await Promise.resolve("foo");
v.thisWillThrow;
} catch (error) {
// "TypeError: Cannot read property 'thisWillThrow' of null"
error.message;
}
}
Итак, просто используйте всю логику кодаtry/catch
Можно ли это сделать, окружив его? Не совсем. Код ниже выдастunhandled promise rejection. await
преобразует отклоненное обещание в перехватываемую ошибку, ноreturn
нет.
run();
async function run() {
try {
// 注意这里是return,不是await
return Promise.reject(new Error("Oops!"));
} catch (error) {
// 代码不会执行到这里
}
}
также невозможно использоватьreturn await
обойти.
Еще одним недостатком является то, что использованиеtry/catch
После этого трудно использовать.
синтаксис для цепочки промисов.
Использование синтаксиса Go
Другим распространенным способом является использованиеthen()
пришлось бы использоватьcatch()
для преобразования захваченного и обработанного промиса в обычный промис. Затем, как и в Go, используйтеif(err)
для обработки исключений.
run();
async function throwAnError() {
throw new Error("Oops!");
}
async function noError() {
return 42;
}
async function run() {
// The `.then(() => null, err => err)` 来匹配正常/异常的情况。如果正常情况,返回`null`;如果异常,返回`err`
let err = await throwAnError().then(() => null, err => err);
if (err != null) {
err.message; // 'Oops'
}
err = await noError().then(() => null, err => err);
err; // null
}
Если вы действительно хотите вернуть и ошибку, и правильное значение, вы можете полностью притвориться, что находитесь в Go.
run();
async function throwAnError() {
throw new Error("Oops!");
}
async function noError() {
return 42;
}
async function run() {
// The `.then(v => [null, v], err => [err, null])` pattern
// 你可以使用数组解构来匹配err和返回值
let [err, res] = await throwAnError().then(
v => [null, v],
err => [err, null]
);
if (err != null) {
err.message; // 'Oops'
}
err = await noError().then(v => [null, v], err => [err, null]);
err; // null
res; // 42
}
Использование обработки ошибок в стиле Go не избавляет от этого.return
Неуловимая ситуация. И это усложняет весь код, если вы забудетеif(err != null)
, будет проблема.
В общем, есть два существенных недостатка:
- Код чрезвычайно повторяющийся, и каждое место необходимо
if (err != null)
, действительно утомительно, и его легко пропустить; -
run()
Неасинхронные ошибки в функциях также не могут быть обработаны;
В целом ничем не лучшеtry/catch
Насколько лучше.
используется при вызове функцииcatch()
try/catch
И пойти на языковые аномалии в стиле языка имеют свои собственные сценарии использования, но лучший способ обрабатывать все исключенияrun()
последующее использование функцииcatch()
,нравится:run().catch()
. Другими словами, используйтеcatch()
иметь дело сrun
Все ошибки в функции, не дляrun
В каждом случае напишите код для соответствующей обработки.
run()
.catch(function handleError(err) {
err.message; // Oops!
})
// 在handleError中处理所有的异常
// 如果handleError出错,则退出。
.catch(err => {
process.nextTick(() => {
throw err;
});
});
async function run() {
await Promise.reject(new Error("Oops!"));
}
Помните,асинхронные функции всегда возвращают промисы. Обещание будет отклонено всякий раз, когда в функции есть исключение. Кроме того, если асинхронная функция возвращает промис, который отклоняется, промис будет продолжать отклоняться.
run()
.catch(function handleError(err) {
err.message; // Oops!
})
.catch(err => {
process.nextTick(() => {
throw err;
});
});
async function run() {
// 注意:这里使用了return,而不是await
return Promise.reject(new Error("Oops!"));
}
зачем использоватьrun().catch()
а не весьrun()
функцияtry/catch
А как насчет завернуть? Сначала рассмотрим ситуацию: еслиtry/catch
изcatch
Есть исключения, что делать? Есть только один путь: вcatch
затем используйте внутрьtry/catch
. так,run().catch()
Шаблон делает обработку исключений очень лаконичной.
Суммировать
Нам лучше иметь глобальный обработчик ошибок для обработки исключений, которые не учитываются, например, использованиеrun().catch(handleError)
, вместоrun()
Добавьте все возможные ошибки в функциюtry/catch
.
О Фундебаге
FundebugСосредоточьтесь на JavaScript, апплете WeChat, мини-игре WeChat, апплете Alipay, React Native, Node.js и мониторинге ошибок онлайн-приложений Java в режиме реального времени. С момента официального запуска Double Eleven в 2016 году Fundebug обработала в общей сложности более 1 миллиарда ошибок, включая Sunshine Insurance, Walnut Programming, Lizhi FM, Head 1:1, Weimai, Youth League Club и многие другие бренды. Бесплатная пробная версия приветствуется!
Уведомление об авторских правах
Пожалуйста, указывайте автора при перепечаткеFundebugИ адрес этой статьи:ошибка blog.fun.com/2019/07/24/…