Mecanismo de bucle de eventos JS en el navegador

Directorio

  • Mecanismo de bucle de eventos
  • Macro tareas y micro tareas
  • Estudio de caso
  • Referencia

1. Mecanismo de bucle de eventos

Mecanismo de bucle de eventos del navegador

La ejecución del navegador del código JS puede dividirse aproximadamente en tres pasos, y la reciprocidad de estos tres pasos constituye el mecanismo de bucle de eventos JS (ver figura).

El primer paso: ejecutar el código completo JS o la función de devolución de llamada (es decir, tarea de macro) en el subproceso principal (subproceso del motor JS), almacenar el objeto en el montón durante la ejecución y agregar los tipos y funciones básicos a la pila (pila ), Se lanzará el montón o se saldrá de la pila después de la ejecución. Después de la ejecución de esta macro tarea, determinará si la cola de micro tareas (cola de microtask) está vacía. Si no está vacía, eliminará todas las micro tareas en secuencia y las ejecutará. Si alguna API web se activa durante este proceso, se realizará el segundo paso.

El segundo paso: llame a la API web y agregue la función de devolución de llamada a la cola de eventos cuando sea apropiado. Por ejemplo, implementado setTimeout(callback1, 1000), se creará un temporizador, y en otro hilo (el navegador activar periódicamente el hilo) que controlan el temporizador ha expirado, esperar hasta después de que expire el temporizador, la devolución de llamada correspondiente callback1unirse a la pila de eventos de devolución de llamada.

Paso 3: Después de completar la ejecución de microtask en el primer paso, determinará si la pila de devolución de llamada de eventos (cola de eventos) está vacía. Si no está vacío, eliminará y ejecutará la función de devolución de llamada que primero ingresa a la cola, el proceso de ejecución es como el primer paso. Si está vacío, esperará o suspenderá el hilo principal según corresponda.


Nota complementaria: el núcleo del navegador es de subprocesos múltiples, y los subprocesos residentes son el subproceso de representación de la GUI del navegador, el subproceso del motor de JavaScript, el subproceso de activación del temporizador del navegador, el subproceso de activación del evento del navegador y el subproceso de solicitud asíncrono http del navegador.


2. Macro tareas y micro tareas

Macrotasks: script (código general), setTimeout / setInterval, E / S, representación de UI, etc.

Microtasks: Promise, MutationObserver, etc.


Diagrama esquemático del proceso de ejecución del código JS de la ejecución de macro tareas y micro tareas:

Diagrama esquemático de la ejecución de macro tareas y micro tareas

Como se muestra en la figura, se puede ver que durante la ejecución de JS, se ejecuta primero una macro tarea, y luego se ejecuta la micro tarea correspondiente generada por esta macro tarea. Una vez completada la ejecución, la macro tarea posterior se ejecuta una y otra vez.


3. Análisis de casos

Use un navegador: Chrome Versión 80.0.3987.163

El primer grupo:

Compare setTimeout y Promise

console.log('start')

setTimeout(() => {
  console.log('setTimeout')
}, 0);

Promise.resolve().then(() => {
  console.log('microtask: promise')
})

console.log('end')

El resultado:

Compare setTimeout y Promise

Análisis:

Para analizar el mecanismo de bucle de eventos JS. En primer lugar, el script (código general) es una tarea macro. Después de la ejecución, generará "inicio" y "fin" sucesivamente, y luego ejecutará la micro tarea generada en este proceso, es decir, la devolución de llamada en promis.then, salida "microtask: promise" ; En este proceso, también se llama a setTimeout en la API web, se creará un temporizador y la devolución de llamada se agregará a la pila de devolución de llamada de evento después de la expiración; luego ejecute la devolución de llamada (segunda tarea de macro) y genere "setTimeout". De acuerdo con el resultado de la operación del navegador, como se esperaba.


El segundo grupo:

Comparación del orden de ejecución de macro tareas y micro tareas

function func1() {
  console.log('func1')
  Promise.resolve().then(() => {
    console.log('microtask.promise1')
  })
}

function func2() {
  console.log('func2')
  Promise.resolve().then(() => {
    console.log('microtask.promise2')
  })
}

function main() {
  func1()
  func2()
  setTimeout(func1, 0);
  setTimeout(func2, 0);
}

main()

El resultado:

Comparación del orden de ejecución de macro tareas y micro tareas

Análisis:

Se puede ver en los resultados de salida que cuando se ejecuta una macro tarea, ejecutará todas las micro tareas correspondientes. Una vez completada la ejecución, las macro tareas posteriores se ejecutarán una y otra vez, de acuerdo con las expectativas.


4. Referencia

Modelo de concurrencia y bucle de eventos

JavaScript evento loop

JavaScript Event Loop Explicado

Serie HTML: macrotask y microtask

【Traducción】 Promesas / especificaciones A +

Supongo que te gusta

Origin www.cnblogs.com/forcheng/p/12746392.html
Recomendado
Clasificación