Hace unas horas estaba leyendo este post donde una persona explica como poder cambiar de cadenas de promesas a un mundo síncrono con async/await. Sin emgargo, el problema con async/await es la necesidad de usar try/catch para poder tener un fallback de cuando una promesa truena.
Efectivamente cambias esto:
const myFn = () => {
myPromise
.then(response => {
console.log('here')
})
.catch(error => {
console.log('error here')
})
}
a
const myFn = async () => {
let response
try {
response = await myPromise
} catch (error) {
response = error
}
}
Básicamente no hay mejora, pues el código sigue siendo igual de complicado de leer, además si no manejas el catch de la promesa rota, el intérprete te va a regresar una excepción.
Entonces en el post, @avishkardalvi nos explica una forma de poder escapar del async/await hell concentrando varias respuestas de estas promesas en un solo lugar y posteriormente regresando una tupla [error, respuesta]
.
Siento que es una buena forma de darle la vuelta a este problema, pero le faltó un poquito para que fuera redonda.
Entonces ESTE es mi approach para el mismo problema, basado en la propuesta original.
const aP = async promise => {
let res, err
try {
res = await promise
} catch (e) {
err = e
}
return [err, res]
}
const algo = async _ => {
const p = new Promise(resolve => resolve('success'))
const s = await aP(p)
const p2 = new Promise((_, reject) => reject('error'))
const s2 = await aP(p2)
console.log(s, s2)
}
algo()
Esto nos va a contestar en cada respuesta de aP
una tupla con el formato [error, response]
y eliminando todas las necesidades de tener que meter try/catch en cada una de las promesas y al mismo tiempo conservando la legibilidad del código resultante.
Esto se compone de dos partes:
Parte 1
El helper
const aP = async promise => {
let res, err
try {
res = await promise
} catch (e) {
err = e
}
return [err, res]
}
aP (corto para async promise) es una función que recibe una promesa tal cual, define los dos posibles resultados, intenta ejecutar la promesa y aqui está el único try/catch necesario, observemos que aP es una función async, es decir que incluso la función misma regresa una promesa que se pude encolar con otras promesas.
Parte 2
La implementación
const algo = async _ => {
const p = new Promise(resolve => resolve('success'))
const s = await aP(p)
const p2 = new Promise((_, reject) => reject('error'))
const s2 = await aP(p2)
console.log(s, s2)
}
algo()
Aquí simplemente definimos una función async donde tenermos dos ejemplos de promesas p
y p2
, donde p
contesta con un resolve (ejemplo todo cool) y p2
contesta con un reject (ejemplo de una promesa rota)
Ambas promesas las pasamos por el aP
quien intenta resolverlas y regresarnos una respuesta. El resultado es el siguiente:
Promise { <pending> }
[ undefined, 'success' ] [ 'error', undefined ]
Como pueden ver, en ambos casos, la tupla se genera corréctamente y no hay ningún warning acerca de que hubo un reject sin catch que rompiera la promesa.
¿Qué piensan de esta solución? ¿Les sería útil?
Coméntame en el telegram
Recuerda si algo de lo que escribo te sirve, no dudes en compartirlo, o éntrale al patreon si deseas ayudarme con un cafecin para seguir escribiendo este tipo de babosadas
Zero out