Finally
Clase 2 de 35 min de lectura
Hay tareas que tienes que hacer sí o sí, salga bien o mal la cosa: cerrar un archivo, liberar un recurso… Para eso existe finally, el bloque que le faltaba al try/catch de la clase anterior y que siempre se ejecuta.
¿Cómo funciona y para qué sirve?#
finally es un bloque opcional que se añade después de try/catch. Es como apagar la luz al salir de casa: haya ido bien o mal el día, la apagas.
Su código se ejecuta siempre, sin importar si:
- El código de
trytermina correctamente. - Ocurre un error y se ejecuta
catch. - Hay un
returndentro detryo decatch.
try { // Código que puede fallar console.log("Ejecutando código...")} catch (error) { // Manejo de errores console.log("Error:", error.message)} finally { // ✅ Este código SIEMPRE se ejecuta console.log("Limpieza completada")}Sintaxis completa#
La estructura completa tiene tres bloques:
try { // Código a intentar ejecutar} catch (error) { // Manejo de errores (opcional)} finally { // Código que siempre se ejecuta (opcional)}Ejemplos prácticos#
Ejemplo 1: Limpieza de recursos
Abres un archivo y, pase lo que pase, hay que cerrarlo. Fíjate en que tanto try como catch tienen un return:
function procesarArchivo(archivo) { let recurso = null try { console.log("Abriendo archivo...") recurso = abrirArchivo(archivo) console.log("Procesando datos...") let datos = procesarDatos(recurso) return datos } catch (error) { console.log("Error procesando archivo:", error.message) return null } finally { // ✅ Siempre cerrar el archivo, haya error o no if (recurso) { console.log("Cerrando archivo...") cerrarArchivo(recurso) } }}Sin finally tendrías que repetir el cierre en los dos caminos. Así lo escribes una sola vez.
Ejemplo 2: Finally con return
¿Y qué pasa si el propio finally tiene un return? Que gana él:
function ejemplo() { try { return "valor desde try" } catch (error) { return "valor desde catch" } finally { // ⚠️ Si pones return aquí, sobrescribe los otros returns return 'valor desde finally' }}ejemplo() // -> 'valor desde finally'Finally vs return#
Lo más sorprendente de finally es que se ejecuta incluso cuando hay un return. Sigue el orden de los mensajes:
function conReturn() { try { console.log("1. En try") return "Desde try" } finally { console.log("2. En finally") } console.log("3. Después de try/finally") // ❌ Nunca se ejecuta}console.log("Resultado:", conReturn())// Salida:// "1. En try"// "2. En finally"// "Resultado: Desde try"El return deja preparado el valor, pero antes de entregarlo se ejecuta finally.
Try/finally sin catch#
Si solo te interesa la limpieza, puedes prescindir de catch:
function soloFinally() { try { console.log("Ejecutando operación...") operacionRiesgosa() } finally { console.log("Limpieza ejecutada") }}// Si ocurre un error, finally se ejecuta pero el error se propagaOjo: aquí nadie captura el error. finally limpia y el error sigue su camino.
Orden de ejecución#
El orden es siempre el mismo:
try: se ejecuta primero.catch: solo si hay un error.finally: siempre, al final.
function mostrarOrden() { console.log("Antes de try/catch/finally") try { console.log("1. En try") throw new Error("Error de prueba") } catch (error) { console.log("2. En catch") } finally { console.log("3. En finally") } console.log("Después de try/catch/finally")}mostrarOrden()// Salida:// "Antes de try/catch/finally"// "1. En try"// "2. En catch"// "3. En finally"// "Después de try/catch/finally"Los puntos clave de finally#
En resumen
finallyse ejecuta siempre: haya error o no, e incluso si hay unreturn.- Es el sitio ideal para el código de limpieza y la liberación de recursos.
- Se puede usar con
catcho sin él. - Evita el
returndentro definally: sobrescribe los demás.