Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

298
Vistas
Callback function executing in the call stack even when it's not empty

When the click event is fired from the mouse, it behaves as expected:

First the listener 1 is pushed into the stack where it queues promise 1 in Microtask Queue(or Job Queue). When listener 1 is popped off, the stack becomes empty. And the promise 1 callback is executed before the listener 2(which is waiting in the Task Queue(or Callback Queue). After promise 1 callback is popped off, the listener 2 is pushed into the stack. So the output is :

Listener 1 Microtask 1 Listener 2 Microtask 2

However when the click is triggered via JavaScript code, it behaves differently:

The callback is pushed into the stack even before the click() function is completed (i.e. call stack is not empty). The output here is :

Listener 1 Listener 2 Microtask 1 Microtask 2

enter image description here

Here's the code:

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>

My understanding is that items from Task Queue and Microtask Queue only get pushed into the Call Stack when it's empty. I might have made wrong assumptions. Please feel free to correct me. Thank you

about 4 years ago · Santiago Gelvez
2 Respuestas
Responde la pregunta

0

Your observations are correct and the explanation is quite straightforward:
The microtask queue only gets visited when the JavaScript execution context stack (a.k.a. call-stack) is empty, (defined in cleanup after running a script, itself called by call a user's operation). Technically the event loop has quite a few calls to perform a microtask checkpoint, but the cases where the JS call-stack can be non-empty are so rare they can be disregarded.

Dispatching an Event through eventTarget.dispatchEvent() is synchronous, no new task is queued, the callbacks are just called from the current context, and moreover, the JS call stack is not empty.

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

So the microtask queue doesn't get visited either, it will only be after the JS call stack is done, which in your code is when the original click event's handler job is executed completely.

However Events dispatched "natively" by the engine will create a new JS job per callback, and thus between each of them the JS call stack will be empty, and the microtask queue will get visited.

about 4 years ago · Santiago Gelvez Denunciar

0

As long as the <button onclick> is running, the .then() won't be executed.

This snippet shows the difference in the execution order a bit better:

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda