javascriptwebapievent-loop

When exactly is the setTimeout callback put on the macrotask queue?


At which point during the JavaScript event loop does it figure out that a timer has reached its target time and needs to be placed on the macroQueue? Does it do this check after completing each macroQueue/microQueue task, or after the whole batch of macroQueue/microQueue tasks? The event loop has a certain order it runs these tasks and I’m wondering where exactly in this process that the callback is actually added to the macroQueue; I’m not asking when the callback itself gets processed. How exactly does the webapi get that callback into that queue within the event loop order of execution.


Solution

  • Depending on how implemented, "figuring out" when a timer has expired is probably achieved by receiving a message from the O/S that a requested timer has elapsed.

    In response to time interval completion, the browser queues a task on the "timer task source". This task is responsible ensuring that code strings passed to a JavaScript timer are compiled into a function, and running the callback supplied in the the timer call. It also will create a new timer with the same timer id and parameters if the timer call used was setInterval.

    As per notes made in Event loop definitions

    Essentially, task sources are used within standards to separate logically-different types of tasks, which a user agent might wish to distinguish between. Task queues are used by user agents to coalesce task sources within a given event loop.

    Task queues are sets, not queues, because the event loop processing model grabs the first runnable task from the chosen queue, instead of dequeuing the first task.

    The microtask queue is not a task queue.

    In summary, tasks for timer callbacks become runnable when the browser is notified of their timer completion and a task to make the callback is queued on the timer task source.The browser may or may not implement multiple task queues in the event loop (say for network access requests, UI events, timers etc.) but if it does so, it appears that the manner of choosing which queue from which to run a runnable task is left to the browser and not covered in standards.

    Note that the microtask queue doesn't really come into it. The (microtask) queue is blocking and any and all jobs in it will run successively until the queue is empty before returning to the event loop's task manager proper.


    See also: (external links)