При написании асинхронных функций очень распространены как обещания, так и асинхронные решения.Даже в одном и том же проекте разные разработчики используют разные привычки.Однако сравнение между ними не является предметом этой статьи.Его можно суммировать только в одном предложении: «async — это идеальное решение для асинхронного программирования».
При использовании асинхронных функций во многих статьях предлагается использовать try catch для отлова исключений, но на самом деле я читал коды многих проектов, и коды не соблюдаются строго, многие из них бесполезны, и даже функция catch не написана Почему?Шерстяное сукно?
Давайте сначала посмотрим на пример кода в случае использования try catch:
Пример 1: Использование try-catch
function getUserInfo () {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject('请求异常')
}, 1000)
})
}
async function logined () {
try {
let userInfo = await getUserInfo()
// 执行中断
let pageInfo = await getPageInfo(userInfo?.userId)
} catch(e) {
console.warn(e)
}
}
logined()
После выполнения он будет захвачен в catch 请求异常
, а затем функция getUserInfo прервет выполнение, что логично.Для интерфейсов с зависимостями прерывание выполнения позволяет избежать сбоев программы.Единственная проблема здесь в том, что try catch вроде бы занимает слишком много строк Если кажется немного избыточным писать каждый интерфейс.
Пример 2: прямой захват
Учитывая, что при нормальных обстоятельствах await
за командой следует объект Promise, поэтому в приведенном выше коде можно естественным образом найти решение для оптимизации:
function getUserInfo () {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject('请求异常')
}, 1000)
})
}
async function logined () {
let userInfo = await getUserInfo().catch(e => console.warn(e))
// 执行没有中断,userInfo 为 undefined
if (!userInfo) return // 需要做非空校验
let pageInfo = await getPageInfo(userInfo?.userId)
}
logined()
После выполнения catch может нормально ловить исключение, но программа не прерывается, а возвращаемое userInfo
значение undefined
, поэтому если так написано, то надо проверять возвращаемое значение на ненулевое значение, if (!userInfo) return
я думаю, что это немного контрлогики, и выполнение должно прерываться при возникновении исключения;
предположение
Нет необходимости прерывать, когда ожидание ненормальное, можно написать так, нужно сделать ненулевую проверку, и консоль не выдаст сообщение об ошибке
let userInfo = await getUserInfo().catch(e => console.warn(e))
if (!userInfo) return
Нужно прерывать, когда ожидание ненормально, и заботиться об ошибке консоли, вы можете написать так
try {
let userInfo = await getUserInfo()
// 执行中断
let pageInfo = await getPageInfo(userInfo?.userId)
} catch(e) {
console.warn(e)
}
Если вам нужно прерваться, когда ожидание ненормально, но вас не волнует консольная ошибка, вы можете написать так
let userInfo = await getUserInfo().catch(e => {
console.warn(e)
return Promise.reject(e) // 会导致控制台出现 uncaught (in promise) 报错信息
})
// 执行中断
let pageInfo = await getPageInfo(userInfo?.userId)
Подведем итог:
Несколько способов написания, на первый взгляд, вы можете подумать, что третий способ написания catch — лучший, но, подумав об этом, с точки зрения пользовательского опыта, я думаю, что try catch — лучший, логичный и интуитивно понятный, в строке с синхронным мышлением программирования консоль не будет показывать uncaught (in promise)
сообщение об ошибке ;
Улавливание (отклонение внутри) цепного вызова является методом обратного вызова традиционного промиса.Поскольку используется метод синхронного программирования async await, кажется ненужным использовать метод цепочки улавливания.