Vue.js: mecanismo de bucle de eventos

1. Introducción al mecanismo de bucle de eventos.       

        JS es un lenguaje de subproceso único. Los navegadores y Node.js definen su propio Event Loop (mecanismo de bucle de eventos) para resolver problemas asincrónicos. El programa se divide en "hilo principal (pila de ejecución)" y "hilo de bucle de eventos", el "hilo principal" ejecuta tareas sincrónicas secuencialmente de arriba a abajo, y el "hilo de bucle de eventos" empuja las tareas asincrónicas a la cola de tareas macro y cola de micro tareas implementar.

        El mecanismo de bucle de eventos nos dice la secuencia de ejecución del código JavaScript en su conjunto. Event Loop es un bucle de eventos, que se refiere a un mecanismo del navegador o Nodo que resuelve el problema del no bloqueo cuando javaScript se ejecuta con un solo subproceso, es decir, A menudo utilizamos el principio asincrónico. El "hilo de bucle de eventos" primero ejecuta la cola de macrotareas y luego ejecuta la cola de microtareas. Si se genera una nueva microtarea durante la ejecución de la microtarea, continuará ejecutando la microtarea. Después de que la microtarea sea ejecutado, volverá a la tarea macro Siguiente ciclo. Es decir, continúe ejecutando primero la cola de macrotareas y luego ejecute la cola de microtareas.

Tarea macro:

script(整体代码)/setTimeout/setInterval/setImmediate/ I/O / UI Rendering

Microtareas:

process.nextTick()/Promise/Async、Await(实际就是Promise)/MutationObserver(html5新特性)

setTimeout y setInterval son fuentes de tareas y las tareas que distribuyen en realidad ingresan a la cola de tareas.

prioridad

setTimeout = setInterval 一个队列setTimeout > setImmediate process.nextTick > Promise

2. Preguntas clásicas de la entrevista de bucle de eventos

1. El siguiente fragmento de código es una pregunta de prueba clásica sobre este tipo de preguntas en la entrevista, que incluye tareas sincrónicas y asincrónicas, y cuál es el orden de varios resultados.

setTimeout(function(){
    console.log('1')
});
new Promise(function(resolve){
    console.log('2');
    resolve();
}).then(function(){
    console.log('3')
});
console.log('4');
// 2,4,3,1

        Primero, divida las tareas, sincronice las tareas: new Promise(), console.log('4'); macro tareas : setTimeout(); micro tareas : Promise().then(); Event Loop empuja las tareas de sincronización a la ejecución apilar a su vez y ejecutar, cuando encuentre macrotareas o microtareas, empújelas a la cola de macrotask o microtask . Primero ejecute la tarea de sincronización. Después de ejecutar la cola de sincronización, irá a la microcola para buscar la tarea hasta que la microcola esté vacía, y luego irá a la macrocola para buscar la tarea y ejecutarla . Por tanto, la secuencia de ejecución de este programa es:

        new Promise()、console.log('4')、Promise().then()、setTimeout()。

 2. Ejemplo 2

 El resultado de la respuesta es: async2 end => Promise => async1 end => promesa1 => promesa2 => setTimeout

3. Ejemplo 3

        mounted(){
            this.test();

        },
        methods:{
            test(){
                console.log('script start');

                this.async1();

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

                new Promise(resolve => {
                    console.log('Promise')
                    resolve()
                })
                .then(function() {
                console.log('promise1')
                })
                .then(function() {
                console.log('promise2')
                })

                console.log('script end')
            },
            async async1() {
                await this.async2()
                    console.log('async1 end')
            },
            async async2() {
              console.log('async2 end')
            },
        }

En la nueva versión del navegador Chrome, no se imprime como se muestra arriba, porque Chrome está optimizado, la espera se vuelve más rápida y el resultado es:

// inicio del script => fin async2 => Promesa => fin del script => fin async1 => promesa1 => promesa2

Analiza este código:

  • Ejecute el código y comience el script de salida.
  • La ejecución de async1 () llamará a async2 () y luego generará el final de async2. En este momento, se conservará el contexto de la función async1 y luego se saltará la función async1.
  • Cuando se encuentra setTimeout, se genera una tarea macro
  • Ejecute la Promesa y genere la Promesa. Cuando se encuentra entonces, se genera la primera microtarea.
  • Continúe ejecutando el código y finalice el script de salida.
  • Después de ejecutar la lógica del código (se ejecuta la macrotarea actual), se inicia la cola de microtarea generada por la macrotarea actual y se genera la promesa 1. Cuando la microtarea se encuentra, se genera una nueva microtarea.
  •  Ejecute la microtarea generada, genere la promesa2 y se ejecutará la cola de microtarea actual. Ejecución de regreso a async1
  •  La ejecución de await en realidad generará una devolución de promesa, es decir
  • let promesa_ = nueva promesa ((resolver, rechazar) {resolver (indefinido)})
  • La ejecución está completa, ejecute la declaración después de esperar y genere el final de async1
  •  Finalmente, ejecute la siguiente tarea macro, es decir, ejecute setTimeout y genere setTimeout

Tenga en cuenta que el análisis anterior es que la ejecución lenta de await en los navegadores antiguos hace que async1 se ejecute después de ejecutar la microtarea.

Supongo que te gusta

Origin blog.csdn.net/qq_36384657/article/details/123243433
Recomendado
Clasificación