TIL
JavaScript is single-threaded:
- running step by step, in order (not simultaneously)
- However, we have certain operations that can’t be finished immediately (e.g. Http requests, fetch requests, setTimeout()) -> if we have these operations, we don’t want to block your entire script until these operations finish
- Having to wait means that other lines of code cannot execute or move forward
Come forward, asynchronous code execution
- for these operations that take longer, they are handed off to the browser(Web APIs), which is multi-threaded -> we’re kind of ‘detaching’ that code and move on to the rest of our code (kind of saying “you deal with it, I gotta move on”)
- once the browser is done handling that code it needs to communicate back to our code -> usually down in callback functions
e.g. eventListener - we’re actually adding the event listener and are handing it off to the browser so that once the browser detects the event, it has the callback function to run (to let JavaScript know event has occurred).
Stack - think, STACK of PANCAKES.
- When an item or line of code is added to a stack, it is pushed to the top (just like a stack of pancakes) - the top is executed and popped off the stack first.
- Keeps track of the currently executing function or task
- When the function requires some time to complete -> it is handed off to the background/browser and moves on to the next code in the stack (e.g. when setTimeout() is on the stack, the webapis handle the count down and setTimeout pops out of the stack)
Queue - PEOPLE waiting in queue.
- first item added is the first item removed (just like a line of people waiting)
- Queue would consist of callbacks that have to run after setTimeout(), a button click (that has an attached event listener), or a fetch request. They are not added immediately to the stack. Instead, they are added to the queue, waiting to be processed.
- monitored by the event loop
Event loop (within the host environment)
- Continuously monitors a queue of pending tasks
- When the event loop sees that the stack is empty, it checks the message queue for any tasks/events waiting to be processed -> if so, event loop retrieves the next task and adds to the stack
Note:
thenable
callbacks of the promise are called first, then setTimeout callback. Promise callbacks are added to the Job Queue rather than the typical callback queue and therefore have higher priority (Also known as job task or microtask)- Because the callback functions of async code run only when the main stack is empty, there is no guarantee that setTimeout() callback will run exactly after the time you have specified (that is the MINIMUM amount of time elapsed).
- Even setTimeout with a time of 0ms will not run immediately (if main stack is busy).
Asynchronous operations are one of those things that really make my brain itch — but I’m glad that compared to last year, I have a much better understanding of the event loop, stack, and task queue now.
Resources I used:
- Academind’s Udemy JavaScript - The Complete Guide course
- What the heck is the event loop anyway?
- Understanding Event Loop, Call Stack, Event & Job Queue in Javascript by Rahul Sagore