← Volver al listado de artículos
Imagen de perfil de Carlos Alfredo Difilippo Paletti

Autor

Carlos Difilippo

¡Suscríbete!

y mantente al tanto

Puedes darte de baja en el momento que lo desees

Comparte en tus redes

Funciones callback en JavaScript: entiende su propósito y cómo utilizarlas

Algo muy simple pero que nos genera muchas veces confusión, más que nada cuando estamos empezando esto de la programación, es entender que es una función callback, llamado normalmente solo callback. Lo importante es tener en mente que es una función y la pasamos (o recibimos) como parámetro a otra.


En JavaScript las utilizamos muy a menudo, quizás sin darnos cuenta, algunos ejemplos son:

1. Cada vez que hacemos un Array.prototype.map()

const fruits = ['🍎', '🥬', '🥕', '🍉', '🍐'];

const hexFruits = fruits.map((fruit) => {
  return (fruit.codePointAt(0).toString(16))
});

// [ '1f34e', '1f96c', '1f955', '1f349', '1f350' ]
Read-only

Open browser consoleTests

Quizás en un primer momento no lo notamos, pero el parámetro que le estamos pasando a map es una función, nuestro callback. Para verlo mejor lo vamos a extraer:

const fruits = ['🍎', '🥬', '🥕', '🍉', '🍐'];

function emojiToHex(emoji) {
  const hex = emoji.codePointAt(0).toString(16);
  return hex;
}

const hexFruits = fruits.map(emojiToHex);

// [ '1f34e', '1f96c', '1f955', '1f349', '1f350' ]
Read-only

Open browser consoleTests

2. Cuando creamos un timeout o interval:

setTimeout(()=>{
  console.log('ya han pasado 2 segundos');
}, 2000);
Read-only

Open browser consoleTests

En este ejemplo lo vemos más claro, pero nuevamente podemos separar la función para tenerlo más claro:

function twoSeconds(){
  console.log('Ya pasaron los 2 segundos...');
}

setTimeout(twoSeconds, 2000);
Read-only

Open browser consoleTests


Otros usos

Los callbacks nos sirven tanto para funciones síncronas como asíncronas, esto es útil, por ejemplo, cuando hacemos una solicitud a una API:

const getData = async (url, callback) => {
  try {
    const res = await fetch(url);
    const data = await res.json();

    callback(null, data)
  } catch (err) {
    callback(new Error('Ocurrió un error al buscar los datos: ' + err.message), null);
  }
}

getData('https://jsonplaceholder.typicode.com/todos/1', (error, data) => {
  if (error) {
    console.error('Error:', error);
  } else {
    console.log('Datos:', data);
  }
});
Read-only

Open browser consoleTests

En este ejemplo estamos manejando errores con callback. Si todo funciona correctamente, este argumento se pasa como null, y el segundo argumento contiene el resultado de la operación. En caso de error, el primer argumento contendrá un objeto Error, y el segundo argumento será null.

También encontraremos utilidad al guardar algo en el localStorage, o en la base de datos, si estamos en el backend.

Callback en React

En React donde utilizamos mucho un callback es con useEffect, del qué ya escribimos un artículo anteriormente, les dejo el link.


Creando una utilidad propia

Para esto les traigo un caso real, con el que me encontré más de una vez. El equipo de diseño ha creado un lottie para un spinner mientras el usuario inicia sesión, pero hay un problema, nuestra aplicación es demasiado rápida y no se aprecia la animación.

Para lo que tendremos que agregar una demora entre la carga de la animación y la redirección al home. Nuestro código tiene una forma similar a esta:

const showAnimation = () => {
  // Carga y muestra el lottie
}
const redirectToHome = () => {
  // Navega hacia el Home de nuestro sitio
}

const Login = () => {
  showAnimation();
	// ...
	// Lógica de inicio de sesión
  // ...
  redirectToHome();
}
Read-only

Open browser consoleTests

Lo que haremos es crear una función. que se llame waitAndDo que recibirá la cantidad de segundos que desea esperar y la función callback. De esta forma podremos controlar el tiempo de espera para que la animación ocurra antes de navegar.

const WaitAndDo = (seconds, cb) => {
  setTimeout(cb, seconds * 1000);
}

const Login = () => {
  showAnimation();
	// ...
	// Lógica de inicio de sesión
  // ...
  WaitAndDo(2, redirectToHome);
}
Read-only

Open browser consoleTests


En conclusión, los callback nos ayudan a manejar el flujo y podemos controlar salidas de operaciones asícronas, pero debemos tener mucho cuidado con una práctica llamada Callback Hell, que sucede al anidar varias de estás funciones callback, para esos casos existen las Promesas y el uso de async/await que facilitan la escritura (y lectura) de código asíncrono.

Nos damos cuenta cuando caímos en callback hell por que nuestro código se mira algo así:

function loadWebsite() {
  console.log("Loading website...");

  setTimeout(function() {
    console.log("Connecting to server...");
    setTimeout(function() {
      console.log("Authenticating...");
      setTimeout(function() {
        console.log("Fetching user data...");
        setTimeout(function() {
          console.log("Fetching user preferences...");
          setTimeout(function() {
            console.log("Fetching website content...");
            setTimeout(function() {
              console.log("Rendering website...");
              setTimeout(function() {
                console.log("Website loaded successfully!");
              }, 2000);
            }, 2000);
          }, 2000);
        }, 2000);
      }, 2000);
    }, 2000);
  }, 2000);
}

loadWebsite();
Read-only

Open browser consoleTests

Este ejemplo está generado por chat gpt, de openai.

Para seguir profundizando en el tema, te invito a revisar la documentación oficial de Mozilla Developer Network (MDN)