Un callback (llamada de vuelta) en términos comunes es una función que recibe otra función como argumento y la ejecuta en un determinado momento. Para entenderlo mejor usaremos un ejemplo sencillo.

Nota: Puedes utilizar de la Consola de Desarrollador de Chrome (en MAC: Cmd + Option + J o en Windows: Ctrl + Shift + J) e ir poniendo a prueba estos ejemplos.

Primero vamos a escribir una función que hará una suma de dos valores y el resultado lo pasará a una función callback que lo presentará en forma de un mensaje de texto en consola:

function add(value1, value2, callback) {
    const result = value1 + value2;
    callback(result);
}
function myCallback(result) { 
    console.log(`Result: ${result}`);
}

Ahora ejecutamos la función add:

add(2, 5, myCallback);

Nos presenta:

Result: 7

Pero que a ocurrido exactamente. Una de las ventajas que nos brinda JavaScript es la facilidad de poder utilizar funciones en todo momento y como mejor se adapten a nuestras necesidades. En este ejemplo estamos declarando 2 funciones, la primera es add la misma que recibe 3 parámetros un value1 que sería el primer número de nuestra suma, un value2 que sería el segundo y un callback que a diferencia de los parámetros anteriores no seria un numero sino una función y que a su vez se ejecutará cuando la suma esté completa.

La segunda función de este ejemplo es myCallback la cual simplemente recibe un valor y lo presenta a manera de mensaje en consola. Lo interesante aquí es que en lugar de llamar a myCallback de manera independiente, la vamos a pasar como un argumento al momento de ejecutar la función suma de la siguiente manera:

add(3, 6, myCallback)

En este ejemplo estamos almacenando el valor de la función callback en una variable llamada myCallback pero también podemos pasarla como una función anónima (sin nombre) directamente a la función add al momento de ejecutarla de la siguiente manera:

add(4, 4, function (unResultado) { 
    console.log(`Result: ${unResultado}`);
});

Obtendremos como resultado:

Result: 8

¿Para qué sirven los callbacks en JavaScript?

Los callbacks son muy útiles para manejar la un comportamiento asíncrono en nuestro código. En javascript a diferencia de otros lenguajes, el código no se ejecuta de manera secuencial es decir que el intérprete de javascript no necesariamente tiene que esperar a que finalice una tarea asíncrona (por ejemplo una llamada a una base de datos) antes de avanzar a la siguiente línea de código, es aquí que el uso de callbacks tiene una gran utilidad ya que son funciones que pueden ser ejecutados en cualquier momento.

Para entender de mejor manera vamos a utilizar un ejemplo valiéndonos de la función setTimeout para simular una ejecución asíncrona:

function runAsyncTask() {
    console.log(1);
    setTimeout(function() {
  	console.log(2);
    }, 1000);
    console.log(3);
}

Ahora la ejecutamos:

runAsyncTask();

Obtenemos el siguiente resultado:

1
3
2

En este ejemplo setTimeout recibe un callback que se ejecutará después de un segundo por esta razón el 2 aparece después del 3.

Ahora vamos a nombrar a nuestra función callback de la siguiente manera:

function myCallback() {
    console.log('This is a callback')
}
function runAsyncTask(callback) {
  console.log(1)
  setTimeout(callback, 1000);
  console.log(3)
}

Ahora ejecutamos la función runAsyncTask

runAsyncTask(myCallback);

Y obtenemos el siguiente resultado:

1
3
This is a callback

Otro uso bastante común de los callbacks es en el manejo de eventos, por ejemplo al momento de hacer clic en un botón deberíamos tener una lógica parecida a la siguiente:

document.getElementById("button1").addEventListener("click", function() {
  // do something
});

En este caso addEventListener recibe 2 parámetros, el primero es el nombre del evento y el segundo es un callback que se ejecutará al momento de que el usuario haga clic sobre el botón con el id  button1.

Entender cómo funcionan los callback en JavaScript es fundamental a la hora de programar en este lenguaje, además de ser la base para otros conceptos como las promesas y el async/await que posee actualmente JavaScript y que analizaremos más a fondo en un próximo artículo.