- The browser uses an event loop to effectively switch between scripting, rendering, painting, networking, eventing, and similar other jobs.
- Although JS is single-threaded, concurrency is possible with help of an Event loop and a bunch of Web APIs.
The task is code to be executed until completion. For each turn of the event loop, one task is executed. A task can schedule other tasks (asynchronous in nature). Multiple task queues are maintained by the browser.
Task sources are - DOM Manipulation, UI Events, History Traversal, Networking
Taking into account the use of
setTimeout, it helps us defer code execution. After resetting of timer for each
setTimeout method, the callback function will be pushed to the tasks queue for processing. Each timer runs separately from the main thread. This way it does not block the main thread.
This is code that needs to be executed after the currently executing task is completed.
Tasks (Macro, Microtasks) can schedule more tasks and they get added to their respective queues. Microtasks are kind of blocking in nature. Unlike macro tasks, the main thread will be blocked until the microtask queue is empty. All of it will be processed in the same turn of the event loop
Microtask sources are - Promise.resolve, Promise.reject, MutationObservers, IntersectionObservers etc.
The blocking nature of microtasks can be exhibited in the above code by increasing the iterations in for loop to a large value.
The microtasks queue is processed before the next rendering and painting jobs. If they are long-running then it will lead to visual degradation.
The summarised version of the event loop algorithm -
- Process the oldest task from the tasks queue
- If there is a microtasks queue, process all entries until its emptied
- Do rendering, painting, and so forth
- Repeat the above steps if the tasks queue is not empty, otherwise wait