Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

286
Views
Función de devolución de llamada que se ejecuta en la pila de llamadas incluso cuando no está vacía

Cuando el evento de clic se activa desde el mouse, se comporta como se esperaba:

Primero, el oyente 1 se inserta en la pila donde pone en cola la promesa 1 en Microtask Queue (o Job Queue). Cuando se quita el oyente 1, la pila se vacía. Y la devolución de llamada de la promesa 1 se ejecuta antes que el oyente 2 (que está esperando en la Cola de tareas (o Cola de devolución de llamada). Después de que se retira la devolución de llamada de la promesa 1, el oyente 2 se inserta en la pila. Por lo tanto, el resultado es:

Oyente 1 Microtarea 1 Oyente 2 Microtarea 2

Sin embargo, cuando el clic se activa a través del código JavaScript, se comporta de manera diferente:

La devolución de llamada se inserta en la pila incluso antes de que se complete la función click() (es decir, la pila de llamadas no está vacía). La salida aquí es:

Oyente 1 Oyente 2 Microtarea 1 Microtarea 2

ingrese la descripción de la imagen aquí

Aquí está el código:

 window.onload = function(){ document.getElementById("myBtn").addEventListener('click', () => { Promise.resolve().then(() => console.log('Microtask 1')); console.log('Listener 1'); } ); document.getElementById("myBtn").addEventListener('click', () => { Promise.resolve().then(() => console.log('Microtask 2')); console.log('Listener 2'); } ); } function clickB(){ document.getElementById("myBtn").click(); }
 <!DOCTYPE html> <html> <button id="myBtn">Manual Click</button> <button onclick="clickB()">JS Click</button> </html>

Tengo entendido que los elementos de Task Queue y Microtask Queue solo se envían a Call Stack cuando está vacío. Podría haber hecho suposiciones equivocadas. Por favor, siéntase libre de corregirme. Gracias

about 4 years ago · Santiago Gelvez
2 answers
Answer question

0

Sus observaciones son correctas y la explicación es bastante sencilla:
La cola de microtareas solo se visita cuando la pila de contexto de ejecución de JavaScript (también conocida como pila de llamadas) está vacía (definida en la limpieza después de ejecutar una secuencia de comandos , a la que llama la operación de un usuario ). Técnicamente, el ciclo de eventos tiene bastantes llamadas para realizar un punto de control de microtarea , pero los casos en los que la pila de llamadas JS no puede estar vacía son tan raros que pueden ignorarse.

El envío de un evento a través de eventTarget.dispatchEvent() es síncrono , no se pone en cola ninguna tarea nueva, las devoluciones de llamada solo se llaman desde el contexto actual y, además, la pila de llamadas JS no está vacía .

 const target = new EventTarget(); target.addEventListener("foo", () => console.log("new foo event")); console.log("before"); target.dispatchEvent(new Event("foo")); console.log("after");

Por lo tanto, la cola de microtareas tampoco se visita, solo será después de que se complete la pila de llamadas JS, que en su código es cuando el trabajo del controlador del evento de clic original se ejecuta por completo.

Sin embargo, los eventos enviados "de forma nativa" por el motor crearán un nuevo trabajo JS por devolución de llamada y, por lo tanto, entre cada uno de ellos, la pila de llamadas JS estará vacía y se visitará la cola de microtareas.

about 4 years ago · Santiago Gelvez Report

0

Mientras se esté ejecutando <button onclick> , .then() no se ejecutará.

Este fragmento muestra un poco mejor la diferencia en el orden de ejecución:

 window.onload = function() { [document.body, myBtn].forEach(node => { node.addEventListener("click", function(e) { const { currentTarget, target } = e; new Promise((r) => { console.log( "Promise()", currentTarget.tagName ) r(); }).then(() => { console.log( ".then()", currentTarget.tagName ) }); }); }); }
 <button id="myBtn" onclick="console.log('hello world');">Manual Click</button> <button onclick="myBtn.click(); console.log('I will happen before the then');">JS click</button>

about 4 years ago · Santiago Gelvez Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!