## Notes JavaScript runs on a single [[computer thread]] but is non-blocking. This means it can continue to run while it waits for async operations such as - Reading from a file - Fetching data from an API - Waiting for user input ## Execution - JavaScript runs in a **single execution context** - This is a call **stack** - Operates on LIFO: **last in, first out** basis ## Non-blocking Behavior - [[#Event Loop]] - callback queues - asynchronous APIs ### Event Loop Responsible for managing the execution of code, events, and messages. 1. **Call stack**: Pushes the execution context of functions onto *call stack* and executes them one at a time 2. **Web/Node APIs**: When JavaScript encounters async operations (setTime(), fetch(), i/o file), it delegates them to the corresponding Web or NodeJS APIs 3. **Callback Queue**: After an async operation is complete, the callback is added to the callback queue 4. **Event Loop**: constantly monitors the call stack and callback queue. If the call stack is empty, pushes the first callback from the queue to the call stack for execution #### Example ```javascript console.log("Start"); setTimeout(() => { console.log("This is asynchronous"); }, 2000); console.log("End"); ``` 1. `console.log("Start")` is 1. Placed in the call stack 2. Executed 3. Removed from the call stack 2. `setTimeout()` is placed in the call stack 1. Sets the callback function to `await` the **WebAPI** (which handles the async operation) 2. `setTimeout()` is popped off the stack 3. `console.log("End")` is 1. Pushed on the stack 2. Executed 3. Removed from the call stack 4. After 2 seconds, the `setTimeout` callback is moved to the Callback Queue, where it waits for the Call Stack to be empty 5. **Event Loop** checks if the Call Stack is empty. 1. Callback function is removed from the Callback Queue 2. Callback function is pushed on to the Call Stack 3. Executed and prints `"This is asynchronous"` 4. Callback function is removed ### Callbacks, Promises, Async & Await - **Callback functions** are functions that are passed as arguments to a function. The callback function is executed once the asynchronous operation is complete - **Promises** represent the result of an asynchronous operation - It allows for `.then()` chaining to handle the result once finished ```javascript fetch(/* ... */) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.log(error)) ``` - **async/await** is syntactic sugar over **Promises**. It enables code to be written in a more declarative manner ```javascript async function fetchData() { try { let response = await fetch(/* ... */); let data = await response.json(); console.log(data); } catch (error) { console.log(error); } } ``` ## References - [Why is JavaScript Single Threaded - Geeks for Geeks](https://www.geeksforgeeks.org/javascript/why-javascript-is-a-single-thread-language-that-can-be-non-blocking/)