Alternativas
Una alternativa a esto:
async function main() {
try {
var quote = await getQuote();
console.log(quote);
} catch (error) {
console.error(error);
}
}
sería algo como esto, usando promesas explícitamente:
function main() {
getQuote().then((quote) => {
console.log(quote);
}).catch((error) => {
console.error(error);
});
}
o algo como esto, usando el estilo de paso de continuación:
function main() {
getQuote((error, quote) => {
if (error) {
console.error(error);
} else {
console.log(quote);
}
});
}
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 devuelto var 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()
da 1
como valor de retorno, f2()
arroja 1
como excepción:
function f1() {
return 1;
}
function f2() {
throw 1;
}
Ahora llamemos al mismo código millones de veces, primero con f1()
:
var sum = 0;
for (var i = 0; i < 1e6; i++) {
try {
sum += f1();
} catch (e) {
sum += e;
}
}
console.log(sum);
Y luego cambiemos f1()
a f2()
:
var sum = 0;
for (var i = 0; i < 1e6; i++) {
try {
sum += f2();
} catch (e) {
sum += e;
}
}
console.log(sum);
Este es el resultado que obtuve para f1
:
$ time node throw-test.js
1000000
real 0m0.073s
user 0m0.070s
sys 0m0.004s
Esto es lo que obtuve por f2
:
$ time node throw-test.js
1000000
real 0m0.632s
user 0m0.629s
sys 0m0.004s
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.