Estoy profundizando en la función async / await del nodo 7 y sigo tropezando con un código como este
function getQuote() {
let quote = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
return quote;
}
async function main() {
try {
var quote = await getQuote();
console.log(quote);
} catch (error) {
console.error(error);
}
}
main();
Esta parece ser la única posibilidad de resolver / rechazar o devolver / lanzar con async / await, sin embargo, ¿v8 no optimiza el código dentro de los bloques try / catch?
¿Hay alternativas?
node.js
async-await
ecmascript-2017
Patricio
fuente
fuente
Respuestas:
Alternativas
Una alternativa a esto:
sería algo como esto, usando promesas explícitamente:
o algo como esto, usando el estilo de paso de continuación:
Ejemplo original
Lo que hace su código original es suspender la ejecución y esperar
getQuote()
a que se resuelva la promesa devuelta por . Luego continúa la ejecución y escribe el valor devueltovar quote
y luego lo imprime si la promesa se resolvió, o lanza una excepción y ejecuta el bloque catch que imprime el error si la promesa fue rechazada.Puede hacer lo mismo usando la API de Promise directamente como en el segundo ejemplo.
Actuación
Ahora, para la actuación. ¡Probémoslo!
Acabo de escribir este código:
f1()
da1
como valor de retorno,f2()
arroja1
como excepción:Ahora llamemos al mismo código millones de veces, primero con
f1()
:Y luego cambiemos
f1()
af2()
:Este es el resultado que obtuve para
f1
:Esto es lo que obtuve por
f2
:Parece que puede hacer algo así como 2 millones de lanzamientos por segundo en un proceso de un solo subproceso. Si está haciendo más que eso, es posible que deba preocuparse por ello.
Resumen
No me preocuparía por cosas así en Node. Si este tipo de cosas se usan mucho, los equipos de V8, SpiderMonkey o Chakra lo optimizarán eventualmente y todos lo seguirán; no es que no esté optimizado como principio, simplemente no es un problema.
Incluso si no está optimizado, todavía diría que si está maximizando su CPU en Node, probablemente debería escribir su número en C; para eso son los complementos nativos, entre otras cosas. O tal vez cosas como node.native serían más adecuadas para el trabajo que Node.js.
Me pregunto cuál sería un caso de uso que necesita lanzar tantas excepciones. Por lo general, lanzar una excepción en lugar de devolver un valor es, bueno, una excepción.
fuente
try catch
, no de lanzar una excepción. Si bien los números son pequeños, es casi 10 veces más lento según sus pruebas, lo cual no es insignificante.Alternativa similar al manejo de errores en Golang
Debido a que async / await usa promesas bajo el capó, puede escribir una pequeña función de utilidad como esta:
Luego impórtelo siempre que necesite detectar algunos errores y envuelva su función asíncrona que devuelve una promesa con ella.
fuente
Una alternativa al bloque try-catch es await-to-js lib. Yo lo uso a menudo. Por ejemplo:
Esta sintaxis es mucho más limpia en comparación con try-catch.
fuente
Alternativamente, en lugar de declarar una posible var para mantener un error en la parte superior, puede hacer
Aunque eso no funcionará si se lanza algo como un error de tipo o un error de referencia. Puede asegurarse de que es un error regular aunque con
Mi preferencia por esto es envolver todo en un gran bloque try-catch donde se crean múltiples promesas que pueden hacer que sea engorroso manejar el error específicamente con la promesa que lo creó. Con la alternativa de ser múltiples bloques try-catch que encuentro igualmente engorrosos
fuente
Una alternativa más limpia sería la siguiente:
Debido al hecho de que cada función asincrónica es técnicamente una promesa
Puede agregar capturas a las funciones cuando las llama con await
No es necesario intentar la captura, ya que se manejan todos los errores de promesas y no tiene errores de código, ¡puede omitir eso en el padre!
Digamos que está trabajando con mongodb, si hay un error, es posible que prefiera manejarlo en la función que lo llama en lugar de hacer envoltorios o usar try catches.
fuente
Me gustaría hacerlo de esta manera :)
Es similar a manejar errores con
co
fuente
await
.catch
En mi experiencia, actuar de esta manera es peligroso. Se detectará cualquier error arrojado en toda la pila, no solo un error de esta promesa (que probablemente no sea lo que desea).El segundo argumento de una promesa ya es una devolución de llamada de rechazo / falla. Es mejor y más seguro usar eso en su lugar.
Aquí hay un one-line mecanografiado seguro que escribí para manejar esto:
fuente