# Review Node/Express Week 2
What do I mean by **asynchronous** or **synchronous**?
Well, let's review what **synchronous** code means first before we get into asynchronous code. **Synchronous** code in JavaScript entails having each step of an operation **wait** for the previous step to execute completely. *Meaning, no matter how long the previous operation might take,
the next operation will be waiting for the previous one to finish.*
For example:
```
const second = () => {
console.log('Hello there!');
}
const first = () => {
console.log('Hi there!');
second();
console.log('The End');
}
first();
```
Here's a step by step of what the call stack will look like:
(the leftmost function would be at the bottom of the callstack)
**1.** [ first() ]
**2.** [ first(), console.log('Hi there!') ]
**3.** [ first(), second() ]
**4.** [ first(), second(), console.log('Hello there!) ]
**5.** [ first(), second() ]
**6.** [ first(), console.log('The End') ]
**7.** [ first() ]
**8.** [ ] ***empty call stack :)***
Now that we know how to call stack works - let's say we want to run some code that may take some time to run. Some examples of those types of operations would be server/network requests,
image processing (like when a user uploads a profile picture).
```
const processImage = (image) => {
//Doing some operations on image
//Food for thought: What if the file size for this picture is reallyyyy big!? It will DEFINITELY take some time for my machine to process an image.
console.log("Image processed");
};
const networkRequest = (url) => {
//Requesting network resource
//Food for thought: What if my internet connection is really slow...? What if a server is down? (this happens all the time - YouTube is down, IG is down, etc.)
return someData;
};
const greeting = () => {
console.log("Hello World");
};
processImage(logo.jpg);
networkRequest("www.somerandomurl.com");
greeting();
```
Knowing how the call stack works, if `processImage()` takes 20 seconds to complete, `networkRequest` will have to wait *at the least* 20 seconds until processImage is done executing to be pushed onto the call stack.
`And `greeting()` would have to wait until `networkRequest` is done executing...`
This is also what we mean by **BLOCKING** code.
The `processImage` function will be placed onto the call stack, and `networkRequest` won't be placed on the call stack until
`processImage` has finished executing - the `processImage` function is **blocking** `networkRequest` from being placed on the stack.
Hopefully you're beginning to realize that there *has* to be a better way! And there is :)
# Asynchronous?!?!? Wut o_O
Calling a function **"Async"** or **"asynchronous"** just means that it will *"take time"* or *"it will happen in the future, but not right now"*.
Things like network requests and image processing take time, but while these functions are running, we can do *other* things.
*So, what's the solution?*
There are actually **three** ways that we can handle asynchronous functions utilizing the Event Loop.
1. Callbacks
2. Promises
3. Async/Await
So far we've learned about:
**1. Callbacks:**
**Important:** Callbacks are just the naming convention for using JavaScript functions. There isn't a special thing called a 'callback' in the JavaScript language, it's just a convention. Instead of immediately returning some result like most functions, functions that use callbacks take some *time* to produce a result.
We can use callbacks to make our code NON-BLOCKING like so:
```
const networkRequest = () => {
//using a setTimeout to simulate a network request that will take a few seconds to complete.
setTimeout(() => {
console.log('Async code');
}, 2000)
}
console.log('Hello World');
networkRequest();
console.log('The End');
OUTPUT:
Hello World
The End
Async Code
```
**Step by Step of what the code above did:**
**1.** In this code the console.log('Hello World') gets pushed onto the callstack first.
**2.** Once above is finished executing then, networkRequest is placed onto the stack next.
**3.** netWorkRequest invokes setTimeout() which starts a timer for 2 seconds and gets popped off the stack and sent to the Web APIs part of the event loop.
**4.** console.log('The End') get pushed onto the top of the stack.
**5.** Once the timer is up, the callback passed to setTimeout will be sent to the callback queue where it will wait until the callstack is empty to be executed.
**6.** The event loop's one job is to check if the callstack is **empty**, and once the callstack is empty, it will send the first item in the callback queue to the stack.
Now in the early days of JS callbacks were pretty cool!
But then as developers started using it more and more, they noticed they were running into something REALLY scary: ***Callback Hell***.
* http://callbackhell.com/
You may run into this christmas tree looking nested function situation going on.
```
function one() {
setTimeout(function() {
console.log('1. First thing setting up second thing');
setTimeout(function() {
console.log('2. Second thing setting up third thing');
setTimeout(function() {
console.log('3. Third thing setting up fourth thing');
setTimeout(function() {
console.log('4. Fourth thing');
}, 2000);
}, 2000);
}, 2000);
}, 2000);
};
```
Anddddd that's why promises were created! To AVOID callback hell.
**2. Promises**
#### What the heck is a promise?
A **promise** is a JavaScript object that represents the eventual completion or failure of an *asynchronous operation.*
'Promise' is just a word for an object with a value and a status.
You can think of it like an IOU where we owe the result of an asynchronous function later on.
The **value** property holds the ***result*** (return value) of an asynchronous operation and the status holds whether or not that operation was successful.
**A promise can have one of three states:** fulfilled, rejected, or pending.
In this example I'll be making a blog and my app is going to be making a lot of server requests for blog post information. This is the same example that we did in lecture:
<iframe height="400px" width="100%" src="https://repl.it/@Julissa93/AsyncExampleWDF?lite=true" scrolling="no" frameborder="no" allowtransparency="true" allowfullscreen="true" sandbox="allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-modals"></iframe>
In the above example we handled promises in ***two*** ways.
1. **Promise chaining** - using .then()
2. **Async/Await** - syntactic sugar for ^.
#### What's the difference between Promises and Async/Await?
The only difference between async/await and promises is the **syntax**.
* With promises you use ``.then()`` to handle the result of the promise.
* With `async/await` you use the `await` keyword to handle the result of the promise - and it must be used in an `async` function.
#### How do I know *when* to use async/await?
Documentation! Depending on the technology that you're using you'll have to see if the methods that you're using will return a promise.
But, you can assume that functions that are used to communicate with a server or a database would return a promise because these are all operations that can take *time*.
### TBD - may add more things to this document through junior phase if y'all are interested.
#### Resources:
* Here is a really *in depth* article on the event loop and async programming: https://blog.sessionstack.com/how-javascript-works-event-loop-and-the-rise-of-async-programming-5-ways-to-better-coding-with-2f077c4438b5