¿Qué es un callback?

Un callback es una función pasada como parámetro a otra función para que pueda ser ejecutada en un determinado momento.

El fin de meter una función dentro de otra (callback) es especialmente útil y nos va a servir para poder indicar que durante la ejecución de la función principal (la que llama a los callbacks), en un momento preciso de la ejecución de la función (el que nosotros queramos), para que ejecute lo que le hemos pasado en el parámetro callback. Por ejemplo, cuando haya terminado de ejecutar una instrucción o un bloque que realice una llamada al callback (una función pasada en la zona de parámetros de otra función) .

Callbacks síncronos VS callbacks asíncronos diferencias

Dentro de los callbacks tenemos dos tipos:

  • Callbacks síncronos: ejecución de un solo proceso de manera simultánea.
  • Callbacks asíncronos: ejecución de procesos ejecutándose de manera simultánea.

Los callbacks tienen un comportamiento sincrono por defecto. Aunque este comportamiento se puede modificar/alterar utilizando métodos asíncronos como setTimeOut. setTimeOut, ejecuta una función o evalúa una expresión después de un número específico de milisegundos. Durante el transcurso de esos milisegundos se pueden ir ejecutando y resolviendo varios procesos de forma simultánea. Una vez consumido el tiempo de espera, la función que teníamos a la espera también se resolverá.

¿Qué tenemos que tener en cuenta cuando realizamos un callback?

  • Cuando una función va a ser utilizada como un callback, solemos identificar la función con un nombre que deje claro que va a ser un callback un ejemplo: callbackHola. También es muy común utilizar fn en la zona de parametros para saber que lo que pasamos en la zona de parametros es una función.

  • Las funciones que son pasadas como callbacks dentro de la zona de parámetros se escriben sin parentesis () ya que por el momento van a ser ejecutadas, sino que simplemente van a pasarse al interior de dicha función para su ejecución en un momento determinado. Para ejecutarlas dentro de la función donde son pasadas como callback esta vez si que son llamadas con parentesis.

  • No podemos pasar un parametro a un callback que ya si esta se encuentra dentro de la zona de parámetros de una función y esto supondría añadir parentesis y los callbacks en la zona de parámetros no pueden llevarlos ya que sino estamos ejecutando la función y no pasandola como parametro y nos provocará conflictos.

Necesitamos pasarle dos parámetros a la función que llama a los callbacks y posteriormente distribuir dichos callbacks. Vamos a ver un ejemplo:

Ejemplos de callbacks síncronos

Vamos a ver un ejemplo desde JSBIN.com:

Una función necesita ejecutar todas sus instrucciones para poder finalizar su ejecución. Por lo que, una vez llamada la función mundo nos adentramos en su interior, para poder finalizar su ejecución es necesario primeramente ejecutar la instrucción console.log de su interior que contiene un llamada hacía callbackHola(). Por tanto, este será el primer elemento en ejecutarse (el callbackHola). Y posteriormente, una vez se finaliza la ejecución del callback, se realiza la ejecución de la instrucción console.log de la función que realiza la llamada al callback (la función mundo). Y finalmente, como ya no hay más líneas, se detendrá el flujo de ejecución. Por tanto, el flujo de ejecución será callBackHola, y posteriormente mundo.

Esto, claramente es un ejemplo de ejecución sincrona debido a que solamente se ejecuta un proceso de manera simultánea.

Si añadimos otro callback al ejemplo anterior, podemos ver qué mundo llama a dos atributos concretamente dos callback). En este caso, ambos atributos son callbacks. El flujo de ejecucción será entramos en la función mundo y llamamos al callbackHola (primer callback que es llamado), luego lo concatena con mundo y llama al siguiente callback (callbackPresentacion) y finalmente ejecutamos el console.log de mundo.

Vamos a ver otro ejemplo y después los explicamos detalladamente:

El flujo de ejecución de una función que tiene callbacks se ejecutan en el orden de llamada.

Si nos fijamos se ejecuta de forma sincrona. Es decir, secuencialmente, primero una y posteriormente otra. Esto es debido a que se bloquea el hilo de ejecución y de esta forma nos aseguramos que el flujo de ejecución pasa de la forma que queramos nosotros. Paso a paso y función a función.

Ejemplo de callbacks asíncronos

Podemos revertir este comportamiento añadiendo por ejemplo un setTimeOut ¿Qué pasaría si le metemos un settimeout? Que el comportamiento cambiaría a asonicrono ya que continuaría con la ejecución de lo que pueda ir ejecutando sin esperar a que finalice la función anterior. Sin bloquear el hilo vamos.

El resultado con los callbacks en sincrona es sota, caballo y rey. En cambio, si ejecutamos el código del nuevo ejemplo, con callbacks asíncronos, cada segundo nos aparece un elemento en el siguiente orden: rey, sota y caballo. Según su orden de finalización.

Tras 1000 ms (1 segundo):

Tras 2000 ms (2 segundo):

Tras 3000 ms (3 segundo):

¿Cuándo usar callbacks síncronos y cuando callbacks asíncronos?

Dependerá de lo que queramos hacer si queremos una secuencia de tareas secuenciales como imprimir algo en un orden (como el ejemplo de sota caballo y rey), lo recomendable es utilizar callbacks síncronos ya que respetará el orden secuencial y nos aseguraremos de que este orden es correcto.

En cambio, si por ejemplo vamos a realizar una petición REST o una consulta a una BBDD que puede tardar mucho en cargar, la mejor opción es usar callbacks asíncronos. Y que así, podemos ir ejecutando e ir cargando otros elementos o datos sin que se bloquee el hilo de ejecución de JavaScript. Y una vez llegue la respuesta, enviarla a donde sea.

La gracia de los callbacks principalmente es usarlos de forma asincrona ya que son mucho más potentes.

Espero que os haya gustado. Saludos y hasta la próxima