A promise callback may be ready while a button-click task is still running, but it cannot interrupt that task. The microtask queue holds the callback until the current task finishes; then the event loop processes microtasks before moving to another task. section 13.1.2
In the two-button example:
- The first click handler queues a callback with Promise.resolve().then(), even though the promise is already resolved. section 13.1.2
- After the handler finishes, the promise callback runs before the waiting second-button click task. Rendering can occur between tasks, but not before that microtask runs. section 13.1.2
Listing 13.2. Pseudocode for our event loop demo with two queues
<button id="firstButton"></button>
<button id="secondButton"></button>
<script>
const firstButton = document.getElementById("firstButton");
const secondButton = document.getElementById("secondButton");
firstButton.addEventListener("click", function firstHandler(){
Promise.resolve().then(() => { #A
/*Some promise handling code that runs for 4 ms*/ #A
}); #A
/*Some click handle code that runs for 8 ms*/
});
secondButton.addEventListener("click", function secondHandler(){
/*Click handle code that runs for 5ms*/
});
/*Code that runs for 15ms*/
</script>
See the two-button pseudocode that queues a promise callback inside the first click handler. section 13.1.2

