JavaScript Asíncrono: La Guía Completa - Parte 2 - Callbacks

Ronaldo B.1 de agosto de 20229 min de lectura

En este artículo hablaremos sobre las funciones de callback y cómo han ayudado en el desarrollo de JavaScript Asíncrono. Puedes consultar el contenido de la parte 1 de esta serie en este enlace:

JavaScript Asíncrono: La Guía Completa - Parte 1 - ¿Qué es un código asíncrono?

¿Qué son los callbacks?

Una función de callback es básicamente una función que se ejecuta después de otra. Para que esta función se ejecute, generalmente la informamos como parámetro de una función inicial. Para entender mejor este concepto, piensa en el siguiente ejemplo: cuando eras niño, ¿alguna vez recibiste una tarea de tu madre? Tal vez recuerdes haber recibido una lista de tareas. Ejemplo: “lava los platos, barre la sala y organiza tu cuarto.” Hiciste todo eso. Pero, al final del día, ella te dice: “Olvidé otra cosa: saca la basura.” ¿Lo notaste? Hiciste varias tareas, pero al final ella te pasó una más para hacer. Una función de callback funciona de la misma manera. Ejecutamos una función, que realizará varias acciones. Pero también informamos una función en el parámetro, como diciendo: “después de ejecutar todo lo que ya definí, realiza esta otra tarea que está en los parámetros.”

Pero, ¿por qué deberíamos usar una función de callback? En algunos casos, solo queremos ejecutar una acción después de que algo ya ha ocurrido en la página. Ejemplo: imagina que deseamos renderizar una lista de ciudades en una tabla. Sin embargo, la información de las ciudades está viniendo de una API. Entonces, ¿cuándo realizaremos la renderización? Solo cuando tengamos los datos de hecho, ¿no es así? En este caso, podríamos crear una función de renderización que sería el callback de la función principal, que sería la responsable de traer los datos.

Dos ejemplos clásicos de funciones de callback son las funciones setTimeout() y setInterval(), que son nativas de JavaScript. Ambas esperan una función de retorno. Pero, ¿qué te parece si creamos juntos una función de callback? Mira el código a continuación:

function writeHello(callback) {
	console.log('Hello World');
	if (typeof callback == 'function') callback();
}

Hemos creado una función llamada writeHello() que mostrará “Hello World” en la consola. Pero, además de eso, esperamos como parámetro una variable llamada callback. Y observa que en la última línea de la función verificamos cuál es el tipo de la variable, para garantizar que es una función y luego llamamos a esa variable con paréntesis al final de su nombre, dejando claro que es una función de callback

Ahora veamos cómo podríamos ejecutar la función writeHello():

writeHello(function() {
	console.log('Callback Function');
});

Bien interesante, ¿no crees? Llamamos a la función writeHello() y ya informamos una función anónima, una función de callback, que también mostrará un mensaje en la consola.

Si accedemos a la consola al ejecutar este código, veremos el siguiente resultado:

Los dos mensajes se mostraron, ya que ambas funciones se ejecutaron.

Este es el concepto de las funciones de callback. Pero, como mencionamos en el artículo anterior, vamos a crear un sitio que consumirá una API y mostrará la información en la pantalla. ¿Qué te parece si comenzamos a desarrollar este proyecto, poniendo en práctica lo que aprendimos sobre callbacks? ¿Listos? ¡Entonces, vamos!

Todo el código que desarrollemos estará disponible en nuestro GitHub

Primero, expliquemos la estructura del proyecto:

Estructura del Proyecto de Visual Studio Code

Tenemos una carpeta para archivos de estilo, una carpeta para los archivos JS, una carpeta para los archivos de imagen y por último nuestro archivo HTML, archivo de entrada para el proyecto.

En cuanto a herramientas externas, solo utilizaremos Materialize.css para hacer que nuestra página sea un poco más agradable y fácil de estilizar.

Al principio, nuestro proyecto es así:

Nuestro proyecto Hcode Games

Ahora sí, vamos a la lógica del proyecto. Nuestro objetivo es escribir el nombre de un juego en la caja de búsqueda y hacer que los resultados se rendericen en el área de juegos principales. En primer lugar, necesitaremos una función para consumir la API de juegos. Vamos a crear estas funciones dentro de un archivo llamado requests.js, que estará dentro de la carpeta js.

La primera función se llamará getGameByName() y esperará dos parámetros: el nombre del juego que estamos buscando y una función de callback, que es el tema de este artículo. Su código será el siguiente:

function getGameByName(name, callback) {
    let request = new XMLHttpRequest();
    request.open('GET', `https://api.rawg.io/api/games?search=${name}`, true);
    request.onload = () => {
        let response = JSON.parse(request.response);
        if (typeof callback == 'function') callback(response);
    };
    request.send();
}

Explicando la función: vamos a crear una solicitud XML a través de la clase XMLHttpRequest(). Recuerda que enseñamos los diversos recursos de esta clase y cómo manipularla en nuestro Curso Completo de JavaScript.

Continuando con la explicación. Después de crear esta solicitud XML, vamos a acceder a la URL de la API, informando el nombre que esperamos allí en los argumentos de la función. Cuando obtengamos los datos vamos a convertirlos a JSON y, nota ahora, ejecutar la función de callback, informando los datos de los juegos a esta función. Así, podremos hacer lo que deseemos con esa información, es decir, podremos renderizarlas en la pantalla. Necesitamos ahora llamar a esta función que acabamos de crear. El nombre de esta función será initGames().

Antes de eso, volviendo al archivo HTML, abramos una etiqueta