Cómo funciona Javascript: bucle de eventos

Reimpresión: enlace original

¿Qué es un bucle de eventos?

Comenzamos con una afirmación extraña: mientras que el código JavaScript asíncrono (como setTimeout me) está permitido, JavaScript en sí mismo nunca tuvo un concepto directo de asíncrono incorporado hasta ES6. El motor de JavaScript nunca hace nada más que ejecutar un solo bloque del programa en un momento dado.

Entonces, ¿quién le dice al motor JS que ejecute su bloque? De hecho, el motor JS no se ejecuta de forma aislada, sino en un entorno alojado, que para la mayoría de los desarrolladores es un navegador web típico o Node.js. De hecho, hoy en día, JavaScript está integrado en todo, desde robots hasta bombillas. Cada dispositivo individual representa un tipo diferente de entorno de alojamiento para JS Engine.

Común en todos los entornos es un mecanismo incorporado llamado bucle de eventos que maneja la ejecución de múltiples bloques en un programa cada vez que se llama a JS Engine.

Esto significa que un motor JS es solo un entorno de ejecución bajo demanda para cualquier código JS arbitrario. El tiempo para programar el evento (ejecución de código JS) es el entorno circundante.

Entonces, por ejemplo, cuando su programa JavaScript realiza una solicitud Ajax para obtener algunos datos del servidor, configura el código de "respuesta" ("devolución de llamada") en la función, y el motor JS le dice al entorno de alojamiento: "Oye, yo Por ahora estoy pausando la ejecución, pero tan pronto como complete esa solicitud de red y tenga algunos datos, vuelva a llamar a esta función".

Luego, el navegador se configura para escuchar las respuestas de la red y programará una función de devolución de llamada para ejecutarla insertándola en el ciclo de eventos cuando se le deba devolver algo. Miremos la imagen de abajo:

1_FA9NGxNB6-v1oI2qGEtlRQ.png

¿Qué son estas API web? Esencialmente, son subprocesos a los que no tiene acceso y puede llamarlos. Son parte del navegador que inicia la concurrencia. Si es un desarrollador de Node.js, estas son las API de C++.

Entonces, ¿qué es exactamente un bucle de eventos?

1_KGBiAxjeD9JT2j6KDo0zUg.png

El bucle de eventos tiene un trabajo simple: escuchar la pila de llamadas y la cola de devolución de llamadas. Si la pila de llamadas está vacía, el bucle de eventos tomará el primer evento de la cola y lo empujará a la pila de llamadas, ejecutando efectivamente el evento. Tales iteraciones se denominan tics en el ciclo de eventos y cada evento es solo una función de devolución de llamada.

console.log('Hi');
setTimeout(function cb1() { 
    console.log('cb1');
}, 5000);
console.log('Bye');
复制代码

Vamos a "ejecutar" este código y ver qué sucede:

  1. El estado es claro. La consola del navegador se borra y la pila de llamadas está vacía.

1.png

  1. console.log('Hola') se agrega a la pila de llamadas

2.png

  1. Se ejecuta console.log('Hola').

3.png

  1. console.log('Hola') se elimina de la pila de llamadas.

4.png

  1. setTimeout(function cb1() { ... }) se agrega a la pila de llamadas.

5.png

  1. setTimeout(función cb1() { ... }) se ejecuta. El navegador creará el temporizador como parte de la API web. Se encarga de la cuenta atrás para usted.

6.png

  1. setTimeout(function cb1() { ... }) se completó y se eliminó de la pila de llamadas.

7.png

  1. console.log('Bye') se agrega a la pila de llamadas.

8.png

  1. se ejecuta console.log('Adiós').

9.png

  1. console.log('Bye') se elimina de la pila de llamadas.

10.png

  1. Después de al menos 5000 ms, el temporizador finaliza y empuja la devolución de llamada cb1 a la "Cola de devolución de llamada".

11.png

  1. El bucle de eventos cb1 se obtiene de la cola de devolución de llamadas y lo empuja a la pila de llamadas.

12.png

  1. cb1 ejecuta y agrega console.log('cb1') a la pila de llamadas.

13.png

  1. se ejecuta console.log('cb1').

14.png

  1. console.log('cb1') se elimina de la pila de llamadas.

15.png

  1. cb1 se elimina de la pila de llamadas.

16.png

Resumen rápido:

1_TozSrkk92l8ho6d8JxqF_w.gif

Curiosamente, ES6 especifica cómo funciona el bucle de eventos, lo que significa que técnicamente está bajo el control del motor JS, que ya no actúa solo como un entorno de alojamiento. Una de las principales razones de este cambio fue la introducción de Promises en ES6, ya que este último requería acceso a un control directo y detallado sobre las operaciones de programación en la cola del bucle de eventos (que analizaremos en detalle más adelante).

Cómo funciona setTimeout(...)

Es importante tener en cuenta que setTimeout(...) no coloca automáticamente la devolución de llamada en la cola del bucle de eventos. Establece un temporizador. Cuando el temporizador expire, el entorno colocará su devolución de llamada en el bucle de eventos para que algún tick futuro lo recoja y lo ejecute. Echa un vistazo a este código:

setTimeout(myCallback, 1000);

No significa que myCallback se ejecutará en 1000 ms, pero myCallback lo agregará a la cola del bucle de eventos en 1000 ms. Sin embargo, puede haber otros eventos agregados anteriormente en la cola: sus devoluciones de llamada tendrán que esperar.

Vea el código a continuación:

setTimeout(function() {
    console.log('callback');
}, 0);
console.log('Bye');
复制代码

Aunque el tiempo de espera se establece en 0ms, el resultado en la consola del navegador será el siguiente:

Hi
Bye
callback
复制代码

Supongo que te gusta

Origin juejin.im/post/6950488674488287246
Recomendado
Clasificación