¿Por qué las funciones de devolución de llamada son asíncronas en JavaScript? ¿Cómo trabajan?

Las funciones de devolución de llamada a menudo se invocan de forma asincrónica; ellos mismos no son asíncronos (generalmente).

JavaScript es un entorno de subproceso único (ignoremos los trabajadores por ahora). Esto significa que no se puede bloquear en operaciones prolongadas, de lo contrario, todo el sistema se bloqueará hasta que se completen las operaciones. Por lo tanto, JavaScript realiza operaciones largas de forma asincrónica, sin bloqueo. Luego se proporciona una devolución de llamada que la operación invoca cuando se completa. Así es como se proporciona el resultado de la operación.

Por ejemplo, una operación AJAX es larga debido a la tardanza de la red. Entonces, cuando se invoca AJAX, se especifican las devoluciones de llamada que se invocan en caso de éxito o falla. (Curiosamente, AJAX admite la invocación sincrónica, pero ahora está en desuso, excepto en Trabajadores).

Vale la pena señalar que las promesas son ahora un mecanismo preferido en JavaScript a las simples devoluciones de llamada. Y con async / await, es posible usar promesas para escribir código JavaScript asincrónico que parece ser sincrónico.

En realidad es bastante simple:

Cuando configura un controlador de eventos, efectivamente proporciona la dirección de la función a la que se llamará cuando ocurran eventos.

Luego, cuando se dispara un evento, se llama a esa función con los argumentos apropiados, expresando lo que sucedió y para qué (generalmente).