Sync vs Async in JS


API

Updated May 22nd, 2022

Article here and watch this summary here.

Promises: consume via API (example fetch, mongodb) or create your own. Great that they can be chained together. Better than callbacks for error handle because you can have one catch block for all instead of one for each. Same for a catch block if using async/await instead of .then().catch()

See the Fireship video that talks about a loop freezing your code until complete so wrapping the loop in a promise to get the loop off the main thread and execute as a micro task.

Explain that “return new promise” may not get it off the main thread but you need to return Promise.resolve().then(() =>{//put loop here}). catch()

Using async keyword automatically returns the value as Promise.resolve behind the scenes. Whatever gets returned inside of this function gets returned as a promise of that value. It also creates a context for us to use await keyword.

A few pro tips:

A few different ways to handle an error in the catch block, (catch the error obviously OR catch and throw another error OR catch the error and return a value). If you return a value it’s basically like ignoring the error and then providing some replacement value. With this approach the consumer of the promise won’t get an error but we’ll get the resolved value inside of the then callback.

You need to be careful when using async await in a .map or a .forEach function. It won’t actually pause the function in this context. Instead it will run all these promises concurrently, And this might not be the behavior your looking for. If you want to run a loop and have every iteration in the loop await a promise, you need to use a traditional for loop. So you can write anything functions and then write a for loop inside that function and then use the weight keyword inside the loop. This will pause each step of the loop until the promises resolved. Though more often than not, you will want to run things concurrently.

A cool thing you can do is use the awake keyword directly in a for loop. If you have a promise that You know we’ll resolve to an array You can actually just use the await keyword directly in your loop.

Const fruitLoop = async() => {

for await (const emoji of smoothie) {}

}

You can also use The await keyword directly in your conditionals. She can await the resolved value of the promise to see if it’s equal to some other value. Super concise way to write conditional expressions when working with promises.

I Continually Don’t Understand

If code is synchronous by default, and you make an API call or a db operation then don’t we want the code to wait rendering API useless. Yes but they may take along time so they are set up to return promises and not wait by default. It’s up to you to decide which code should wait and which code doesn’t wait.

If fetch returns a promise and db call return promises do I need to make my own promises? Not necessarily but you can if you are returning a value to use in another function.

9 times out of ten you don’t need to create your own promises, you just need to know how to leverage a promise already set up.

The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value.

If I take a look at the API created in the react for the rest of us course, He has wrapped the database operations in the model files in a promise and so he’s able to resolve with specific information. Mine currently are async functions that also have error handling with try catch. I am guessing that by creating a new promise he’s able to resolve or reject with specific messages/values. In the controller file he then uses that resolve, even if empty, block and sends a res.json success message.

I’m the case above, an empty resolve in a model file still triggers a .then () in a controller file.

It’s About Specifying Which Code Should Wait

JS wait’s by default but when an async action like a setTimeout is introduced the subsequent code will not wait so async/await is about moving specific code to the right place so it does wait again!

Fetch and mongoDB methods are already set up to return a promise. Any code below these lines will not wait unless you make some changes.

// old
fetch().then(res => return res.json()).then(data => console.log(data))

// new
async function start() {
  const response = await fetch()
  const data = await response.json()
  console.log(data)
}
start()

Using Async function without new Promise Syntax

Source: the end of learn web code video

Behind the scenes the browser with create a promise and resolve with whatever is returned.

Refactor in FSJS Course

Want to wait for something can’t just say wait, wait for what? Wait for a promise to resolve. We work with promises more than needing to create our own. fetch resolves automatically, mongodb methods resolve automatically. Your own validate function needs to be defined to resolve.

Some functions were refactored later to not use the “return new Promise” syntax and just returned in place of resolve keyword and throw error in place of reject keyword.

An async function automatically returns a promise so you don’t ned to explicitly say “return new Promise((resolve, reject) => {})”

Also refactored to drop wrapper function that’s sole purpose was to prevent the immediate execution of a new Promise. Originally needed because as soon as JS sees Promise, it will try and execute. With asyn c, someone needs to cal the function.