sincronas - promise javascript
Prueba correcta... Captura la sintaxis usando Async/Await (3)
Me gusta la sencillez de la nueva función
Async/Await
disponible en Typecript, etc. Sin embargo, no estoy seguro de que me guste el hecho de que tengo que declarar la variable que estoy
await
en el exterior de un
try...catch
bloquear para usarlo más tarde.
Al igual que:
let createdUser
try {
createdUser = await this.User.create(userInfo)
} catch (error) {
console.error(error)
}
console.log(createdUser)
// business
// logic
// goes
// here
Corríjame si me equivoco, pero parece ser la mejor práctica
no
colocar varias líneas de lógica de negocios en el cuerpo de
try
, por lo que solo me queda la alternativa de declarar
createdUser
fuera del bloque, asignándolo en el bloque , y luego usarlo después.
¿Cuál es la mejor práctica en este caso?
Parece ser la mejor práctica no colocar múltiples líneas de lógica de negocios en el cuerpo de prueba
De hecho, diría que sí.
Por lo general, desea
catch
todas las
excepciones al trabajar con el valor:
try {
const createdUser = await this.User.create(userInfo);
console.log(createdUser)
// business logic goes here
} catch (error) {
console.error(error) // from creation or business logic
}
Si desea detectar y manejar los errores solo de la promesa, tiene tres opciones:
-
Declare la variable afuera y bifurque dependiendo de si hubo una excepción o no. Eso puede tomar varias formas, como
-
asignar un valor predeterminado a la variable en el bloque
catch
-
return
temprano o volver athrow
una excepción del bloquecatch
-
establezca un indicador si el bloque
catch
detectó una excepción y pruébelo en una condiciónif
- prueba del valor de la variable que se ha asignado
let createdUser; // or use `var` inside the block try { createdUser = await this.User.create(userInfo); } catch (error) { console.error(error) // from creation } if (createdUser) { // user was successfully created console.log(createdUser) // business logic goes here }
-
asignar un valor predeterminado a la variable en el bloque
-
Pruebe la excepción capturada para su tipo y maneje o vuelva a lanzarla en función de eso.
try { const createdUser = await this.User.create(userInfo); // user was successfully created console.log(createdUser) // business logic goes here } catch (error) { if (error instanceof CreationError) { console.error(error) // from creation } else { throw error; } }
Desafortunadamente, JavaScript estándar (todavía) no tiene soporte de sintaxis para excepciones condicionales .
-
Use
then
con dos devoluciones de llamada en lugar detry
/catch
. Esta es realmente la manera menos fea y mi recomendación personal también por su simplicidad y corrección, no depender de errores etiquetados o miradas del valor del resultado para distinguir entre el cumplimiento y el rechazo de la promesa:await this.User.create(userInfo).then(createdUser => { // user was successfully created console.log(createdUser) // business logic goes here }, error => { console.error(error) // from creation });
Por supuesto, viene con el inconveniente de introducir funciones de devolución de llamada, lo que significa que no puede
break
/continue
bucles tan fácilmente o hacerreturn
anticipadas de la función externa.
La respuesta de @Bergi es buena, pero creo que no es la mejor manera porque tienes que volver al método anterior (), así que creo que una mejor manera es detectar el error en la función asíncrona
async function someAsyncFunction(){
const createdUser = await this.User.create(userInfo);
console.log(createdUser)
}
someAsyncFunction().catch(console.log);
-
Pero, ¿qué pasa si tenemos muchos
await
en la misma función y necesitamos detectar cada error?
Puede declarar la función
to()
function to(promise) {
return promise.then(data => {
return [null, data];
})
.catch(err => [err]);
}
Y entonces
async function someAsyncFunction(){
let err, createdUser, anotherUser;
[err, createdUser] = await to(this.User.create(userInfo));
if (err) console.log(`Error is ${err}`);
else console.log(`createdUser is ${createdUser}`);
[err, anotherUser] = await to(this.User.create(anotherUserInfo));
if (err) console.log(`Error is ${err}`);
else console.log(`anotherUser is ${anotherUser}`);
}
someAsyncFunction();
Al leer esto es: "Espere a esto. Usuario.crear".
Finalmente, puede crear el módulo "to.js" o simplemente usar el módulo await await-to-js .
Puedes obtener más información sobre cómo funcionar en esta publicación
Otro enfoque más simple es agregar .catch a la función de promesa. ex:
const createdUser = await this.User.create(userInfo).catch( error => {
// handle error
})