## 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/)