Templates literal
Las templates literals 🎨 son una característica dentro de JavaScript que nos permite hacer dos cosas super concretas con una sintaxis súper simple, usando tildes invertidas ` o también llamados grave accent. Primero: Nos permite dar saltos de línea dentro del string y la segunda: poder interpolar variables dentro de una cade de texto o string.
Lector: No entiendo nada de lo que estás diciendo. 🙃
Yo: Mmmh… mejor, veamos algunos ejemplos, porque no me está ayudando el explicar usando solo texto. 🫣
const 🥺 = "Soy un texto que no le
permiten dar saltos de linea"
Si vemos en este ejemplo, estamos declarando una variable con un texto usando comillas dobles (para efectos de este ejemplo usé comillas dobles, pero el resultado será el mismo si usamos comillas simples).
👀 Si nos damos cuenta, el mismo ejemplo nos está marcando de distinto color las letras que están en la segunda línea.
En el ejemplo que veremos a continuación, al estar usando las tildes invertidas, no nos está generando ningún error, es más, se ve como que el color no cambia (no como en el ejemplo anterior).
const 💪 = `Yo si puedo
muajajajaja 😈`;
Ojo ⚠️, que esto no es lo único que se puede hacer con las templates literals, ya que también podemos concatenar variables dentro del mismo string, sin necesidad de hacer cosas extrañas como sumar variables y cosas así. Pero Wait! 🛑, necesitamos utilizar una nueva forma de decirle al string que lo que va a continuación es una variable.
Lector: pff otra cosa más por aprender… 😓
Yo: Tranquilidad, que con los ejemplos que vamos a ver ahora, lo vas a aprender súper rápido. 🚀
Sin templates literal
const usuario = {
nombre: "Arthur",
edad: 30,
};
console.log("Hola! mi nombre es " + usuario.nombre + " y tengo " + usuario.edad + " años.");
// output: Hola! mi nombre es Arthur y tengo 30 años
Con templates literal
const usuario = {
nombre: "Arthur",
edad: 30,
};
console.log(`Hola! mi nombre es ${usuario.nombre} y tengo ${usuario.edad} años.`);
// output: Hola! mi nombre es Arthur y tengo 30 años
En ambos ejemplos tenemos exactamente el mismo resultado. Queríamos poder concatenar/unir texto con variables y esto se pudo lograr de dos maneras, lo cual no está tan malo. Ahora, no te pasa que al ver ambos ejemplos, sientes que uno es más… intuitivo? o por lo menos, más sencillo de leer 📖, y lo único que tuvimos que aprender fue saber cómo envolver las variables dentro del mismo string.
Ahora, siendo un poco más formal con la explicación, para poder interpolar variables, necesitamos “envolver” esta misma entre llaves, anteponiendo el símbolo dólar ($) quedando la siguiente estructura: ${...}
.
Asincronía
En JavaScript, muchas veces necesitamos ejecutar tareas que no se completan de inmediato, como solicitar datos de una API 🌐 o leer un archivo 📂. Estas tareas son conocidas como operaciones asincrónicas ⏳, y nos permiten continuar ejecutando el resto del código sin esperar a que esas tareas se terminen. A esto se le llama asincronía.
Lector: ¿Qué? ¡No entiendo nada!
Yo: Tranquilo, lo explicaré con un ejemplo simple.
Imagínate que tienes una función que espera 2 segundos ⏱️ para darte un resultado. Mientras esperas, ¿qué haces? Pues, sigues trabajando en otras cosas 🛠️, y cuando el resultado llega, lo utilizas. Así es como funciona la asincronía en JavaScript.
console.log("Inicio de la tarea");
setTimeout(() => {
console.log("Esto se ejecuta después de 2 segundos");
}, 2000);
console.log("Fin de la tarea");
En este ejemplo, setTimeout es una función asincrónica que espera 2 segundos antes de ejecutar su código. Mientras tanto, el resto del código sigue ejecutándose sin detenerse. ¡Eso es la magia de la asincronía! ✨
Callbacks
Antes de que existieran las promesas (de las que hablaremos más adelante), las operaciones asincrónicas en JavaScript usaban funciones callback para manejar los resultados. Un callback es simplemente una función que se pasa como argumento a otra función y se ejecuta cuando la operación asincrónica ha finalizado.
Veamos un ejemplo clásico:
function pedirDatos(callback) {
setTimeout(() => {
const datos = { nombre: "Bruce Banner", edad: 56 };
callback(datos);
}, 3000);
}
pedirDatos((resultado) => {
console.log("Datos recibidos:", resultado);
});
Aquí estamos usando un callback para procesar los datos una vez que han sido obtenidos después de 3 segundos. Esta era una de las primeras maneras de manejar la asincronía, pero como veremos más adelante, tiene algunos inconvenientes cuando las operaciones se complican, lo que da lugar a algo llamado Callback Hell 😱.
Promesas
Una promesa 📜 es un objeto que representa el eventual resultado (o fallo) de una operación asincrónica. En lugar de pasar un callback como argumento, las promesas te permiten trabajar con la asincronía de una manera mucho más legible, utilizando los métodos .then(), .catch() y .finally().
Veamos cómo funciona:
const promesaDeDatos = new Promise((resolve, reject) => {
setTimeout(() => {
const exito = true; // Cambia esto a false para ver el catch
if (exito) {
resolve({ nombre: "Bruce Banner", edad: 56 });
} else {
reject("Hubo un error al obtener los datos");
}
}, 3000);
});
promesaDeDatos
.then((resultado) => {
console.log("Datos recibidos:", resultado);
})
.catch((error) => {
console.error("Error:", error);
})
.finally(() => {
console.log("Operación completada");
});
Con las promesas podemos gestionar más fácilmente los resultados exitosos o los errores, evitando el Callback Hell. En este ejemplo, si todo va bien, resolve se ejecuta, y si hay un error, se ejecuta reject. ¡Súper útil! 🚀
Async/Await
Si pensabas que las promesas ya hacían la asincronía más sencilla ¡espera a conocer async/await! 🚀 Esta característica permite que escribamos código asíncrono de una manera aún más limpia y directa. Parece que todo sucede de manera síncrona, pero en realidad está manejando promesas en el fondo.
Para usar async/await, solo necesitas declarar una función como async y usar await para esperar los resultados de las promesas.
Veamos un ejemplo:
async function obtenerDatos() {
try {
const resultado = await promesaDeDatos;
console.log("Datos recibidos:", resultado);
} catch (error) {
console.error("Error:", error);
} finally {
console.log("Operación completada");
}
}
obtenerDatos();
Con async/await, el código parece más lineal y fácil de seguir 👣. En lugar de usar .then() y .catch(), simplemente usamos await para “esperar” el resultado de la promesa. Si algo sale mal, lo manejamos con try/catch, como lo haríamos con código síncrono.