En primer lugar, permítanme explicar que no hay nada malo con el procesamiento try-catch
. Creo que escribir el código de esta manera será un poco lioso. Creo que la lógica del código está rota y es difícil de entender.
El segundo es el problema de la redundancia de código. Un solo try-catch
ocupa varias líneas de código. Si se añade un try-catch
a cada solicitud, el código parecerá hinchado.
Y para un número tan grande de códigos redundantes idénticos, puede sustituirse por una función general.
async/await se introdujo en ES2017 para que las operaciones asíncronas fueran más intuitivas y cómodas y para resolver el problema del infierno de las devoluciones de llamada Promise
.
Cuándo se solicitará una excepción
Todos sabemos que await
suele ir seguido de peticiones asíncronas. Las razones de las anomalías en las peticiones asíncronas son aproximadamente las siguientes:
Debido a problemas de red, ésta se desconecta y la petición no está disponible.
Una red lenta hace que las peticiones asíncronas pierdan tiempo.
¿En qué circunstancias hay que gestionar las excepciones a las peticiones?
Una vez que se produce la situación anterior, la solicitud asíncrona generará una excepción, y JavaScript es un lenguaje de un solo hilo. Después de que el código informe de un error, el código subsiguiente no puede continuar ejecutándose, por lo que es necesario añadir un try-catch
para capturar la petición asíncrona en este momento. Excepción, para que el código pueda continuar ejecutándose hacia atrás.
Pero, ¿es necesario añadir un try-catch para todas las peticiones asíncronas?
He estudiado el código de nuestro proyecto. La petición asíncrona se procesa con un try-catch
. Se dan las siguientes situaciones
Múltiples peticiones asíncronas en serie
try {
const list = await getList(params)
const info = await getListById(list[0]?.id)
} catch {}
El resultado de retorno de la petición asíncrona anterior se utilizará como parámetro de petición de la siguiente petición asíncrona, por lo que una vez que la petición anterior sea anormal, las peticiones posteriores serán anormales, por lo que es necesario añadir el procesamiento try-catch
.
Gestión del estado de carga de las peticiones asíncronas
loading.value = true
try {
const list = await getList(params)
} finally {
loading.value = false
}
Generalmente, antes de procesar una petición asíncrona, le añadiremos un estado de carga, y una vez que se produce la excepción de petición, si no añadimos un try-catch, la página siempre estará en estado de carga. Por lo tanto, es necesario establecer el estado de carga a false finalmente, y necesita ser procesado externamente cuando se procesa en catch.
Entonces, ¿cómo manejamos con gracia try-catch en peticiones asíncronas?
Manejo de promesas
En primer lugar, debe quedar claro: En circunstancias normales, la orden await
va seguida de un objeto Promise
. Por lo tanto, puede utilizar el propio .catch
para capturar excepciones. Como la segunda operación anterior que sólo maneja el estado de carga, puede ser procesada en .catch
, y luego usar el juicio if
para controlar la salida anticipada. No hay necesidad de escribir código try-catch
redundante.
loading.value = true
let res = await getList().catch(() => (loading.value = false))
if (!res) return
Función await-to-js handler
Podemos utilizar el método anterior para peticiones asíncronas simples, pero cuando nos encontremos con múltiples operaciones asíncronas, necesitaremos utilizar la librería await-to-js de la que vamos a hablar hoy. Su introducción es muy sencilla: Se puede ejecutar fácilmente sin errores try-catch Handle
.
Y el código fuente es sencillo, sólo 23 líneas de código, echémosle un vistazo juntos.
/**
* @param { Promise } promise
* @param { Object= } errorExt - Additional Information you can pass to the err object
* @return { Promise }
*/
export function to<T, U = Error>(
promise: Promise<T>,
errorExt?: object
): Promise<[U, undefined] | [null, T]> {
return promise
.then<[null, T]>((data: T) => [null, data])
.catch<[U, undefined]>((err: U) => {
if (errorExt) {
const parsedError = Object.assign({}, err, errorExt)
return [parsedError, undefined]
}
return [err, undefined]
})
}
export default to
El proceso general es el siguiente: La función a acepta los parámetros Promise
y errorExt
. Si la Promise
tiene éxito, devuelve [null, data]
. Si es anormal, juzgará si tiene el parámetro errorExt
(que representa la información adicional pasada al objeto err). Si a veces se fusiona con el err
capturado por el catch
Return
, o [err, undefined]
si no hay ninguno.
Utilización
Instalar
# use npm
npm i await-to-js --save
# use yarn
yarn add await-to-js
Nos sirve para reescribir la primera pregunta anterior:
import to from 'await-to-js'
const [err, data] = await to(getList(params))
if (err) return
const info = await to(getListById(list[0]?.id))
Después de la transformación de la función to, si el primer parámetro devuelto no está vacío, significa que la petición informó de un error, y puede ser devuelto por adelantado. Si no hay primer parámetro, la petición asíncrona tiene éxito.
Gracias por leernos y compartir.