Preguntas de la entrevista de front-end: bucle de eventos de JavaScript (bucle de eventos), macro tareas y micro tareas


El bucle de eventos

Todos sabemos que el motor Js es de subproceso único, lo que significa que cada vez que se ejecutan varios programas, uno debe ejecutarse antes de que se ejecute el otro. Entonces alguien puede preguntar: ¡Por lo general, activamos el temporizador setTimeout y no hemos visto ninguna influencia en el funcionamiento de los siguientes programas! Esto se debe a que javascript ha sido un lenguaje de secuencias de comandos sin bloqueo y de un solo subproceso desde sus inicios. Y su no bloqueo se logra a través de tareas asíncronas , se puede ver que setTimeout es una tarea asíncrona.

Entonces podemos saber a partir de la figura anterior: para lograr tareas asincrónicas, necesitamos usar el módulo webAPI integrado del navegador (subprocesamiento del navegador) para realizar tareas asincrónicas.


setTimeout(()=>{
    
    
	console.log('我是异步')
},2000)
console.log('我是同步')

El proceso de ejecución del código anterior:

  1. Cuando el navegador analiza el código Js en la setTimeoutfunción, la función 入栈encuentra que la función es un código asíncrono y lo divide en el 放入webAPIssubproceso del navegador 开始计时.
  2. El navegador continúa con el código Js console.log('我是同步'), descubre que es un 同步código y 直接abre la pila para 执行mostrar "Soy sincrónico".
  3. Después de casi dos segundos, el navegador divide el hilo (webAPI), coloca la función de temporizador finalizada en la cola de callback queuedevolución de llamada (cola de mensajes), el navegador comienza a atravesar la cola de devolución de llamada, coloca la función de temporizador en la pila para su ejecución inmediata y el impresión de la consola "Soy asíncrono"

Esta operación completa un bucle de eventos.

Nota: el navegador sondeará la cola de devolución de llamada solo cuando no haya ningún programa para ejecutar en la pila de ejecución (si hay una función de devolución de llamada en la cola de devolución de llamada, llévela a la pila de ejecución para su ejecución)

2. Macro tareas/micro tareas

El orden de ejecución del código asincrónico es diferente y no se ejecuta uno por uno de arriba a abajo. Porque las funciones asincrónicas se dividen en tareas macro y tareas micro.
El orden de ejecución es: tarea síncrona -> micro tarea asíncrona -> macro tarea asíncrona

Tarea de macros:

  1. 新程序或子程序被直接执行
  2. 时间的回调函数
  3. setTimeout和setInterval的回调

Microtareas:
1. Promise.then() .catch() .finally()
2. MutationObserver
3.Object.observe

sin representación

// 宏任务
console.log('1')

// setTimeout 的回调是 宏任务,进入回调队列排队
setTimeout(() => {
    
    

    // 宏任务
    console.log('4')
    
    // setTimeout 的回调是 宏任务2,进入回调队列排队
    setTimeout(() => {
    
    
        console.log('7')
    }, 0)
    
    // Promise 的回调是 微任务,本轮调用末尾直接执行
    Promise.resolve()
        .then(() => {
    
    
            console.log('6')
        })
    console.log('5')
}, 0)

// Promise 的回调是 微任务,本轮调用末尾直接执行
Promise.resolve()
    .then(() => {
    
    
        console.log('3')
    })
    
console.log('2')

La secuencia de ejecución del código anterior es una salida de secuencia positiva de 1~7.

Cada tarea macro puede ir seguida de una cola de tareas micro. Si hay una instrucción o método en la cola de tareas micro, se ejecutará; si no, se ejecutará la siguiente tarea macro hasta que se ejecuten todas las tareas macro. La tarea es equivalente a la pequeña cola de la tarea macro.
Por lo tanto, esto no viola el principio de "primero en entrar, primero en salir" de la cola de devolución de llamada. Si una tarea macro va acompañada de una tarea micro, entonces la tarea micro se ejecuta primero, el la macro tarea se coloca primero, y se espera la siguiente micro tarea. Después de ejecutarlas todas, ¡comience a ejecutar la macro tarea nuevamente!


De hecho, la secuencia completa de ejecución del navegador del código Js debería ser: tarea síncrona -> micro tarea asíncrona -> DOM渲染页面-> macro tarea asíncrona

Así es, entre microtareas y macrotareas, el navegador realizará un renderizado DOM, como en el siguiente caso:

con renderizado

//向body添加h1节点,内容为Hello
const $content = $('<h1>Hello</h1>')
$('body').append($content)

console.log(1);

Promise.resolve().then(() => {
    
    
    console.log('2.promise');
    alert('promise then')
})

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

console.log(4);

Proceso de ejecución:
paso 1:
inserte la descripción de la imagen aquí
después de hacer clic en la ventana de alerta para confirmar, paso 2:
inserte la descripción de la imagen aquí
esto prueba la conclusión: tarea síncrona -> micro tarea asíncrona -> DOM渲染页面-> macro tarea asíncrona

Supongo que te gusta

Origin blog.csdn.net/weixin_60297362/article/details/123298178
Recomendado
Clasificación