Microtareas y Macrotareas en Js

1. Introducción

Las tareas se pueden dividir en dos tipos, una es tareas síncronas (synchronous), la otra es asíncrona (asynchronous), y las tareas asíncronas se dividen en macro tareas y micro tareas.

Tareas sincrónicas: tareas que están en cola para su ejecución en el subproceso principal, la siguiente tarea solo se puede ejecutar después de que se complete la tarea anterior;
tareas asincrónicas: tareas que no ingresan al subproceso principal pero ingresan a la "cola de tareas" (task queue) , solo espere el subproceso principal Después de ejecutar la tarea, la "cola de tareas" comienza a notificar al subproceso principal para solicitar la ejecución de la tarea, y la tarea ingresará al subproceso principal para su ejecución

console.log("这是开始");

function fn1() {
    
    
  console.log("这是一条消息2");
  fn2();
}

function fn2() {
    
    
  console.log("这是一条消息3");
}

setTimeout(function cb1() {
    
    
  console.log("这是来自第一个回调的消息");
});

console.log("这是一条消息1");
fn1();

setTimeout(function cb2() {
    
    
  console.log("这是来自第二个回调的消息");
}, 0);

console.log("这是结束");
//输出的结果:
//这是开始
//这是一条消息1
//这是一条消息2
//这是一条消息3
//这是结束
//这是来自第一个回调的消息
//这是来自第二个回调的消息

inserte la descripción de la imagen aquí

2. ¿Qué son las microtareas? ¿Qué es una macrotarea? ¿Qué son?

En JavaScript, las macrotareas y las microtareas son conceptos que se utilizan para administrar operaciones asincrónicas.

Una tarea de macro representa un grupo de código JavaScript que se ejecutará en el subproceso principal. Suelen incluir las siguientes situaciones:

  1. Script de código general: un código de programa completo y ejecutable que consta de varias líneas de código, como<script>js代码</script>
  2. setTimeout y setInterval: código activado por un temporizador.
  3. Operaciones de E/S: incluidas las operaciones asincrónicas, como la lectura de archivos y el envío de solicitudes de red.
  4. Representación de la interfaz de usuario: representación del DOM, es decir, el proceso de cambiar el código para volver a representar el DOM.
  5. requestAnimationFrame: Acciones a realizar antes de que se redibuje la siguiente página.

Orden de ejecución entre tareas de macro: setTimeout --> setInterval --> operación de E/S --> ajax asíncrono

Una microtarea es un conjunto de código JavaScript que debe ejecutarse lo antes posible después de que se complete la ejecución de la tarea actual. Se ejecutan inmediatamente después de que finaliza la fase actual del bucle de eventos, en lugar de esperar a que se ejecute la siguiente macrotarea. Las microtareas comunes incluyen:

  1. Devoluciones de llamada de promesa (luego, atrapar, finalmente): los controladores de promesa se ejecutan como microtareas.
  2. MutationObserver: API para monitorear cambios de DOM.
    3.Object.observe: se usa para monitorear los cambios de objetos en js en tiempo real
  3. process.nextTick (en el entorno Node.js): coloque la función de devolución de llamada en la cola de microtareas.

Orden de ejecución entre microtareas: proceso.nextTick --> Promise

Cuando el motor JavaScript ejecuta código, primero ejecuta la macrotarea actual y luego verifica si la cola de microtareas está vacía. Si la cola de microtareas no está vacía, el motor ejecutará las microtareas en secuencia hasta que la cola de microtareas esté vacía. A continuación, el motor pasa a la siguiente macrotarea. Este proceso continúa en bucle, formando un bucle de eventos (event loop), como se muestra en la siguiente figura.
Orden de ejecución de microtareas y macrotareas

Comprender el orden de ejecución de macrotareas y microtareas es importante para comprender la programación asincrónica de JavaScript. Las macrotareas generalmente se ejecutan después de que finaliza una fase de bucle de eventos, mientras que las microtareas se ejecutan inmediatamente después de que la tarea actual haya terminado de ejecutarse. Esto significa que las microtareas se pueden ejecutar antes que las macrotareas, por lo que tienen mayor prioridad.

3. Caso

Caso número uno

const promise = new Promise((resolve, reject) => {
    
    
  console.log(1);
  setTimeout(() => {
    
    
    console.log("timerStart");
    resolve("success");
    console.log("timerEnd");
  }, 0);
  console.log(2);
});
promise.then((res) => {
    
    
  console.log(res);
});
console.log(4);

Introduce el resultado:

1
2
4
timerStart
timerEnd
success

Análisis de resultados:

  1. Cuando se encuentre primero con el constructor Promise, el contenido del interior se ejecutará primero y se imprimirá 1;
  2. Encuentre el temporizador steTimeout, es una tarea de macro, colóquelo en la cola de tareas de macro;
  3. Continúe ejecutando hacia abajo e imprima 2;
  4. Dado que el estado de Promise todavía está pendiente en este momento, promise.then no se ejecutará primero;
  5. Continúe ejecutando la tarea de sincronización a continuación e imprima 4;
  6. En este momento, no hay tareas en la cola de microtareas, continúe ejecutando la siguiente ronda de macrotareas y ejecute steTimeout;
  7. Primero ejecute timerStart, luego encuentre resolver, cambie el estado de promesa a resuelto y guarde el resultado y
  8. Elpromise.then anterior se inserta en la cola de microtareas y luego se ejecuta timerEnd;
  9. Después de ejecutar la tarea macro, ejecute la promesa de la microtarea e imprima el resultado de resolver.

Caso 2

Promise.resolve().then(() => {
    
    
  console.log('promise1');
  const timer2 = setTimeout(() => {
    
    
    console.log('timer2')
  }, 0)
});
const timer1 = setTimeout(() => {
    
    
  console.log('timer1')
  Promise.resolve().then(() => {
    
    
    console.log('promise2')
  })
}, 0)
console.log('start');

Resultado de salida:

start
promise1
timer1
promise2
timer2

Análisis de resultados:

  1. En primer lugar, Promise.resolve().then es una microtarea, únase a la cola de microtareas
  2. Ejecute timer1, es una tarea de macro, únase a la cola de tareas de macro
  3. Continúe ejecutando el siguiente código síncrono e imprima el inicio
  4. De esta forma, se completa la primera ronda de tareas macro y se inicia la tarea micro Promise.resolve().then y se imprime la promesa1.
  5. Encuentre el temporizador 2, que es una tarea de macro, agréguelo a la cola de tareas de macro. En este momento, la cola de tareas de macro tiene dos tareas, a saber,
    temporizador 1 y temporizador 2;
  6. De esta forma se ha ejecutado la primera ronda de microtareas y se inicia la segunda ronda de macrotareas, primero se ejecuta timer1 y se
    imprime timer1;
  7. Encuentro Promise.resolve().entonces, es una microtarea, únase a la cola de microtareas
  8. Comience a ejecutar las tareas en la cola de microtareas e imprima la promesa2;
  9. Finalmente ejecute la macro tarea timer2 timer e imprima timer2;

Supongo que te gusta

Origin blog.csdn.net/CYL_2021/article/details/130631233
Recomendado
Clasificación