The await is over! Learn how to make your JavaScript Promise code beautiful and concise with async-await https://github.com/codediodeio/async-await-pro-tips

Jake Archibald's Talk: https://youtu.be/cCOL7MC4Pl0
Demos with Angular: https://www.youtube.com/channel/UCYFd7Qy93YP7gPERnxP545A
2024-02-04T07:11:33.992Z
nova-2
2-general-nova
2024-01-09.29447
30089e05-99d1-4376-b32e-c263170674af
7393ef1e-2afc-4292-92ba-f21780d0099a
87e2821239e1686da01c5096dffdaad2e676921fe23a01b8dd143fe497b510e4
67875a7f-c9c4-48a0-aa55-5bdb8a91c34a
deprecated
JavaScript is a single threaded programming language yet everything we do on the web tends to be blocking or time consuming, which means that asynchronous programming is an essential skill for any JavaScript developer.
Today's video will focus primarily on the amazing syntactic sugar provided by AsyncAwait, but before we can get there we really need to understand Things from the ground up starting with the browser or Node.
Js event loop, callbacks, promises, and then finally async await.
And we're going to do this without making a single joke about a sink or a weight.
If you're new here, like and subscribe and we'll be giving away another one of a kind t shirt with this video.
All you to do is leave a comment below and we'll pick a random winner next week.
In order to understand anything async, you really need to first understand the event loop.
This this is Ace.
I hope that clears up any questions you have.
I'm going to give you the general overview, but I highly recommend you watch this talk from Jake Archibald, which is the best of the event loop that I've ever seen.
Then after you're done watching that talk you should check out Steven Fluin's demos with Angular channel which just released a video about callbacks which are one of the that happen within the event loop.
So what is the event loop and what does it have to do with async await?
Both the browser and Node.
Js are always running threaded event loop to run your code.
On the first go around, it will run all of your synchronous code, but it might also queue up asynchronous events to be called back later.
You say, here's a function that I need to run, but first, I need to go get some data from the network.
The event loop says, okay, I'll keep doing my thing while you do your thing in a separate thread pool.
Then at some point in the future, gitData will finish and let the event loop know that it's ready to be called back.
Now this is where things get interesting.
If it's a macro task, like a setTime out or setInterval, it will be executed on the next event loop.
But if it's a microtask, like a fulfilled Promise, then it will be called back before the start of the next event loop.
Let's look at the implications of this by writing some actual code.
First, we will write a console log which is synchronous.
Then we'll throw in a setTimeout, but give it a time delay of 0 milliseconds.
Then we'll have a promise that resolves right away.
And lastly, we will add another console log for one more synchronous line of code.
So nothing here has any actual time delay.
So intuitively, I would think that each line of code would be executed 1 by 1.
But that's not how things work in the event loop.
If we execute this code, you can see the first line gets logged right away because it's running on the main thread.
Then if we run the second line, it's being queued for a future task.
Then the Promise is being queued to run-in the microtask queue immediately after this current task.
And finally, the last console log gets executed right away.
So even though the setTimeout callback was queued up before the Promise, the Promise still gets executed first because of the priority of the microtask queue.
So now that you know how the event loop works, we can start looking at Promises.
1st, I'll show you how a Promise based API might be consumed.
And then we'll look at how we actually create our own Promises from scratch.
So fetch is a browser based API, but it's also available on Node via the Node Fetch library.
And it allows us to hit an HTTP endpoint and have the response returned to us as a Promise of the response.
Fetching data from a remote server is always going to be async, So we can queue up the Promise, then provide it with a callback to map it to JSON.
The great thing about Promises is that we can chain them together.
Mapping to JSON is also a Promise, so we can return that Promise from the original then callback.
And then in the next one, we'll have the actual user data as a plain JavaScript object.
If we go ahead and run this code, you'll see it runs our console log first and then it retrieves the data from the API and console logs that afterwards.
The great thing about promises is that you can catch all errors in the chain with a single function.
We can do this by adding catch to the bottom of our promise chain And it will handle errors that happen anywhere within our asynchronous code.
If this code were callback based, we'd have to have a separate error handler for every single one of the asynchronous operations.
Ends.
So if an error is thrown anywhere in our code, it's going to bypass all of the future then callbacks and go straight to the catch callback.
When you start creating promises, that's when you're more likely to screw things up.
1st, I'm setting up a log function, so I can show you the elapsed time between each line of code.
Up a while loop that loops a 1,000,000,000 times arbitrarily.
If we run this on the main thread, it's going to block all of their code from executing until the 1,000,000,000 loops are done.
So we'll do one console log, run our while loop, and then do another console log after that.
And you can see it takes about 700 milliseconds to finish the while loop.
Our script is essentially frozen until that while loop is complete.
So let's go ahead and wrap this code in a Promise, so we can get it off the main thread and execute it as a micro task.
This is one tricky little way you might screw things up.
So we create a new Promise, we add our code inside that Promise, and then we have it resolved to that value when done.
So you might think that because we're wrapping this in a Promise that we're going to execute this off the main thread.
But the actual creation of the Promise and that big while loop is still happening on the main thread.
It's only the resolving of the value that happens as a microtask.
So the first synchronous line gets logged right away And the second one should too, but there's still a 700 millisecond delay because that while loop is still blocking on the main thread.
So to ensure that all of our synchronous code runs as fast as possible, we'll refactor our code once again to say promise resolve, then we'll run the while loop inside of that resolvePromises callback.
By putting this code inside of a resolve Promise, we can be guaranteed that it will be executed after all of the synchronous code in the current macro task has completed.
If we go ahead and run our script again, you can see we get our 2 console logs right away and then finally the promise resolves after 700 milliseconds.
So now that you know all that stuff, you should be in the clear to use asyncawait responsibly.
We already know that promises are a huge improvement over callbacks, but promises can still be really hard to read and follow, especially when you have a long chain of multiple asynchronous events.
AsyncAwait really just boils down to syntactic Sugar to make your asynchronous code read like synchronous code.
First, let's look at the async part of the equation and see what that does.
Here we have a regular function that does nothing.
And if we put the async keyword in front of it, we have a function that returns a promise of nothing.
So whatever gets returned inside this function will be a Promise of that value.
I'm going to reuse this GetFruit function throughout the lesson just to simulate what a Promise based API looks like.
In this case, the user can pass in the name of a fruit and then the function will resolve to the value of the fruit emoji from this object.
And just to make this a little more clear, if we didn't use the async keyword, we could write this function by just returning a Promise that resolves to this value.
So when you use the async keyword, the magic that happens is that it takes the return value and automatically resolves it as a Promise.
But that's not everything that it does.
It also sets up a context for you to use the await keyword.
The real power of an async function comes when you combine it with the await keyword to pause the execution of the function.
Now, I'm going to write a second async function called make smoothie.
What we need to do is get multiple fruits and then combine them together as a single value.
Instead of chaining together a bunch of then callbacks, we can just have a Promise resolved to the value of a variable.
Await is like saying pause the execution of this function until the GetFruit Promise resolves to a value, at which point we and use it as the variable a.
And then we'll move on to the next line of code.
After we get a pineapple, we can then get a strawberry and then we'll return them together as an array.
One of the most annoying things with Promises is that it's kind of difficult to share resolved values between multiple steps in the Promise chain.
But AsyncAwait solves this problem really nicely.
The code on the right is what this would look like if we wrote it with just regular promises.
And as you can see, there's a lot more code and a lot complexity there.
Now if you're already a JavaScript expert, then I'm kind of trolling you because you know that the code on the left is making the single biggest mistake that people make when using asyncawait, And that is failing to run the code concurrently.
If we go back to the code on the left, you can see that we're waiting for a pineapple to resolve and then we're getting a strawberry afterwards.
But we could get both of these things at the same time.
You really only need to await one thing after the other if the second value is dependent on the first value.
For example, if you need to get a user ID before you can then retrieve some data from the database.
Let's imagine we're making these calls from a remote API and there's about a second of latency.
If we run this code again with a delay, you can see it takes a full second to get the 1st fruit and then a full second to get the 2nd fruit.
But the whole point of the event loop is to avoid blocking code like this.
So we know that an async function always returns a Promise.
So instead of doing one after the other, we can add both of our Promises to Promise dot all.
This will tell all the promises in the array to run concurrently and then have the resolved values be at that index in the array.
So this is something that you should always be thinking about when working with async functions.
You don't want to accidentally pause a function unnecessarily.
So instead of awaiting a whole bunch of individual promises, you might want to add all your promises to an array and then await that Promise.
All call.
And as you can see here, we've doubled the speed of the original function.
Another nice benefit of asyncawait is error handling.
Instead of chaining a catch callback to our Promise chain, we can just wrap our code in a try catch block.
This offers much better flexibility when handling errors that might occur across multiple If we take our code from the last example and throw an error in the middle of it, we can then catch that error down here in the Catch block.
The first thing we'll probably wanna do here is console log the error.
And then we can either catch the error and throw another error or we can catch the error and return a value.
Your decision here will dictate the control flow for the consumer of this Promise.
If you return a value, it's basically like ignoring the error and then providing some replacement value.
So the consumer of the promise won't get an error, but instead they'll get the resolved value inside of the then callback.
In contrast, if we throw an error inside of our catch block, It will break the consumer's promise chain and be handled by their catch callback.
Now I wanna show you a couple of tricks to make your code as sweet as possible.
Let's imagine we have a string of ids, and then we want to retrieve all these ids from the database.
We can use array map to convert them to an array if promises and then resolve them all concurrently using Promise dot all.
That looks great, but you need to be careful when using async await in a map or foreach loop because it won't actually pause the function in this context.
So normally, we would expect this loop to stop if we do await getFruit, but that's actually not what happens in this case.
Instead, it will run all these promises concurrently, so that might not be the behavior that you're expecting.
If you want to run a loop and have every iteration In that loop, a way to promise, you need to use a traditional for loop.
So you can write async functions and then write a for loop inside that function then use the await keyword inside the loop.
When you write your code like this it will pause each step of the loop until that promise is resolved.
But more often than not you'll probably want to run everything concurrently and a cool thing you can do is use the await keyword directly in a for loop.
If you have a Promise that you know resolves to an array, you can actually just use the await keyword directly in your loop.
So you can say 'for await' in your code which will await The array of items to resolve and then loop over them immediately after.
And as you can probably imagine, you can also use the await keyword directly in your conditionals.
On the left side of the conditional, we can await the result value from a Promise and then we can see if it's equal to some other value.
So that gives you a super concise way to write conditional expressions when working with Promises.
Hopefully, that gives you some ideas on what you can do with async await in ES 7 or TypeScript.
It is truly one of the sweetest things to ever happen to JavaScript.
If this video helped you, please like and subscribe and make sure to join the live next week for the t shirt giveaway.
And if you want to take your development to the next level consider becoming a pro member at angularfirebase.com.
You'll get access to all kinds of advanced content designed to help you build and ship your app faster.
Thanks for watching and I'll talk to you soon.

Speaker 0: JavaScript is a single threaded programming language yet everything we do on the web tends to be blocking or time consuming, which means that asynchronous programming is an essential skill for any JavaScript developer. Today's video will focus primarily on the amazing syntactic sugar provided by AsyncAwait, but before we can get there we really need to understand Things from the ground up starting with the browser or Node. Js event loop, callbacks, promises, and then finally async await. And we're going to do this without making a single joke about a sink or a weight. If you're new here, like and subscribe and we'll be giving away another one of a kind t shirt with this video.

All you to do is leave a comment below and we'll pick a random winner next week. In order to understand anything async, you really need to first understand the event loop. This this is Ace. I hope that clears up any questions you have. I'm going to give you the general overview, but I highly recommend you watch this talk from Jake Archibald, which is the best of the event loop that I've ever seen.

Then after you're done watching that talk you should check out Steven Fluin's demos with Angular channel which just released a video about callbacks which are one of the that happen within the event loop. So what is the event loop and what does it have to do with async await? Both the browser and Node. Js are always running threaded event loop to run your code. On the first go around, it will run all of your synchronous code, but it might also queue up asynchronous events to be called back later.

You say, here's a function that I need to run, but first, I need to go get some data from the network. The event loop says, okay, I'll keep doing my thing while you do your thing in a separate thread pool. Then at some point in the future, gitData will finish and let the event loop know that it's ready to be called back. Now this is where things get interesting. If it's a macro task, like a setTime out or setInterval, it will be executed on the next event loop.

But if it's a microtask, like a fulfilled Promise, then it will be called back before the start of the next event loop. Let's look at the implications of this by writing some actual code. First, we will write a console log which is synchronous. Then we'll throw in a setTimeout, but give it a time delay of 0 milliseconds. Then we'll have a promise that resolves right away.

And lastly, we will add another console log for one more synchronous line of code. So nothing here has any actual time delay. So intuitively, I would think that each line of code would be executed 1 by 1. But that's not how things work in the event loop. If we execute this code, you can see the first line gets logged right away because it's running on the main thread.

Then if we run the second line, it's being queued for a future task. Then the Promise is being queued to run-in the microtask queue immediately after this current task. And finally, the last console log gets executed right away. So even though the setTimeout callback was queued up before the Promise, the Promise still gets executed first because of the priority of the microtask queue. So now that you know how the event loop works, we can start looking at Promises.

1st, I'll show you how a Promise based API might be consumed. And then we'll look at how we actually create our own Promises from scratch. So fetch is a browser based API, but it's also available on Node via the Node Fetch library. And it allows us to hit an HTTP endpoint and have the response returned to us as a Promise of the response. Fetching data from a remote server is always going to be async, So we can queue up the Promise, then provide it with a callback to map it to JSON.

The great thing about Promises is that we can chain them together. Mapping to JSON is also a Promise, so we can return that Promise from the original then callback. And then in the next one, we'll have the actual user data as a plain JavaScript object. If we go ahead and run this code, you'll see it runs our console log first and then it retrieves the data from the API and console logs that afterwards. The great thing about promises is that you can catch all errors in the chain with a single function.

We can do this by adding catch to the bottom of our promise chain And it will handle errors that happen anywhere within our asynchronous code. If this code were callback based, we'd have to have a separate error handler for every single one of the asynchronous operations. Ends. So if an error is thrown anywhere in our code, it's going to bypass all of the future then callbacks and go straight to the catch callback. When you start creating promises, that's when you're more likely to screw things up.

1st, I'm setting up a log function, so I can show you the elapsed time between each line of code. Up a while loop that loops a 1,000,000,000 times arbitrarily. If we run this on the main thread, it's going to block all of their code from executing until the 1,000,000,000 loops are done. So we'll do one console log, run our while loop, and then do another console log after that. And you can see it takes about 700 milliseconds to finish the while loop.

Our script is essentially frozen until that while loop is complete. So let's go ahead and wrap this code in a Promise, so we can get it off the main thread and execute it as a micro task. This is one tricky little way you might screw things up. So we create a new Promise, we add our code inside that Promise, and then we have it resolved to that value when done. So you might think that because we're wrapping this in a Promise that we're going to execute this off the main thread.

But the actual creation of the Promise and that big while loop is still happening on the main thread. It's only the resolving of the value that happens as a microtask. So the first synchronous line gets logged right away And the second one should too, but there's still a 700 millisecond delay because that while loop is still blocking on the main thread. So to ensure that all of our synchronous code runs as fast as possible, we'll refactor our code once again to say promise resolve, then we'll run the while loop inside of that resolvePromises callback. By putting this code inside of a resolve Promise, we can be guaranteed that it will be executed after all of the synchronous code in the current macro task has completed.

If we go ahead and run our script again, you can see we get our 2 console logs right away and then finally the promise resolves after 700 milliseconds. So now that you know all that stuff, you should be in the clear to use asyncawait responsibly. We already know that promises are a huge improvement over callbacks, but promises can still be really hard to read and follow, especially when you have a long chain of multiple asynchronous events. AsyncAwait really just boils down to syntactic Sugar to make your asynchronous code read like synchronous code. First, let's look at the async part of the equation and see what that does.

Here we have a regular function that does nothing. And if we put the async keyword in front of it, we have a function that returns a promise of nothing. So whatever gets returned inside this function will be a Promise of that value. I'm going to reuse this GetFruit function throughout the lesson just to simulate what a Promise based API looks like. In this case, the user can pass in the name of a fruit and then the function will resolve to the value of the fruit emoji from this object.

And just to make this a little more clear, if we didn't use the async keyword, we could write this function by just returning a Promise that resolves to this value. So when you use the async keyword, the magic that happens is that it takes the return value and automatically resolves it as a Promise. But that's not everything that it does. It also sets up a context for you to use the await keyword. The real power of an async function comes when you combine it with the await keyword to pause the execution of the function.

Now, I'm going to write a second async function called make smoothie. What we need to do is get multiple fruits and then combine them together as a single value. Instead of chaining together a bunch of then callbacks, we can just have a Promise resolved to the value of a variable. Await is like saying pause the execution of this function until the GetFruit Promise resolves to a value, at which point we and use it as the variable a. And then we'll move on to the next line of code.

After we get a pineapple, we can then get a strawberry and then we'll return them together as an array. One of the most annoying things with Promises is that it's kind of difficult to share resolved values between multiple steps in the Promise chain. But AsyncAwait solves this problem really nicely. The code on the right is what this would look like if we wrote it with just regular promises. And as you can see, there's a lot more code and a lot complexity there.

Now if you're already a JavaScript expert, then I'm kind of trolling you because you know that the code on the left is making the single biggest mistake that people make when using asyncawait, And that is failing to run the code concurrently. If we go back to the code on the left, you can see that we're waiting for a pineapple to resolve and then we're getting a strawberry afterwards. But we could get both of these things at the same time. You really only need to await one thing after the other if the second value is dependent on the first value. For example, if you need to get a user ID before you can then retrieve some data from the database.

Let's imagine we're making these calls from a remote API and there's about a second of latency. If we run this code again with a delay, you can see it takes a full second to get the 1st fruit and then a full second to get the 2nd fruit. But the whole point of the event loop is to avoid blocking code like this. So we know that an async function always returns a Promise. So instead of doing one after the other, we can add both of our Promises to Promise dot all.

This will tell all the promises in the array to run concurrently and then have the resolved values be at that index in the array. So this is something that you should always be thinking about when working with async functions. You don't want to accidentally pause a function unnecessarily. So instead of awaiting a whole bunch of individual promises, you might want to add all your promises to an array and then await that Promise. All call.

And as you can see here, we've doubled the speed of the original function. Another nice benefit of asyncawait is error handling. Instead of chaining a catch callback to our Promise chain, we can just wrap our code in a try catch block. This offers much better flexibility when handling errors that might occur across multiple If we take our code from the last example and throw an error in the middle of it, we can then catch that error down here in the Catch block. The first thing we'll probably wanna do here is console log the error.

And then we can either catch the error and throw another error or we can catch the error and return a value. Your decision here will dictate the control flow for the consumer of this Promise. If you return a value, it's basically like ignoring the error and then providing some replacement value. So the consumer of the promise won't get an error, but instead they'll get the resolved value inside of the then callback. In contrast, if we throw an error inside of our catch block, It will break the consumer's promise chain and be handled by their catch callback.

Now I wanna show you a couple of tricks to make your code as sweet as possible. Let's imagine we have a string of ids, and then we want to retrieve all these ids from the database. We can use array map to convert them to an array if promises and then resolve them all concurrently using Promise dot all. That looks great, but you need to be careful when using async await in a map or foreach loop because it won't actually pause the function in this context. So normally, we would expect this loop to stop if we do await getFruit, but that's actually not what happens in this case.

Instead, it will run all these promises concurrently, so that might not be the behavior that you're expecting. If you want to run a loop and have every iteration In that loop, a way to promise, you need to use a traditional for loop. So you can write async functions and then write a for loop inside that function then use the await keyword inside the loop. When you write your code like this it will pause each step of the loop until that promise is resolved. But more often than not you'll probably want to run everything concurrently and a cool thing you can do is use the await keyword directly in a for loop.

If you have a Promise that you know resolves to an array, you can actually just use the await keyword directly in your loop. So you can say 'for await' in your code which will await The array of items to resolve and then loop over them immediately after. And as you can probably imagine, you can also use the await keyword directly in your conditionals. On the left side of the conditional, we can await the result value from a Promise and then we can see if it's equal to some other value. So that gives you a super concise way to write conditional expressions when working with Promises.

Hopefully, that gives you some ideas on what you can do with async await in ES 7 or TypeScript. It is truly one of the sweetest things to ever happen to JavaScript. If this video helped you, please like and subscribe and make sure to join the live next week for the t shirt giveaway. And if you want to take your development to the next level consider becoming a pro member at angularfirebase.com. You'll get access to all kinds of advanced content designed to help you build and ship your app faster.

Thanks for watching and I'll talk to you soon.
JavaScript is a single threaded programming language yet everything we do on the web tends to be blocking or time consuming, which means that asynchronous programming is an essential skill for any JavaScript developer. Today's video will focus primarily on the amazing syntactic sugar provided by AsyncAwait, but before we can get there we really need to understand Things from the ground up starting with the browser or Node.
programming
Js event loop, callbacks, promises, and then finally async await. And we're going to do this without making a single joke about a sink or a weight. If you're new here, like and subscribe and we'll be giving away another one of a kind t shirt with this video. All you to do is leave a comment below and we'll pick a random winner next week. In order to understand anything async, you really need to first understand the event loop. This this is Ace. I hope that clears up any questions you have. I'm going to give you the general overview, but I highly recommend you watch this talk from Jake Archibald, which is the best of the event loop that I've ever seen. Then after you're done watching that talk you should check out Steven Fluin's demos with Angular channel which just released a video about callbacks which are one of the that happen within the event loop. So what is the event loop and what does it have to do with async await? Both the browser and Node. Js are always running threaded event loop to run your code.
On the first go around, it will run all of your synchronous code, but it might also queue up asynchronous events to be called back later. You say, here's a function that I need to run, but first, I need to go get some data from the network. The event loop says, okay, I'll keep doing my thing while you do your thing in a separate thread pool.
programming
Then at some point in the future, gitData will finish and let the event loop know that it's ready to be called back. Now this is where things get interesting. If it's a macro task, like a setTime out or setInterval, it will be executed on the next event loop. But if it's a microtask, like a fulfilled Promise, then it will be called back before the start of the next event loop.
Let's look at the implications of this by writing some actual code. First, we will write a console log which is synchronous. Then we'll throw in a setTimeout, but give it a time delay of 0 milliseconds. Then we'll have a promise that resolves right away. And lastly, we will add another console log for one more synchronous line of code.
programming
So nothing here has any actual time delay.
So intuitively, I would think that each line of code would be executed 1 by 1. But that's not how things work in the event loop. If we execute this code, you can see the first line gets logged right away because it's running on the main thread. Then if we run the second line, it's being queued for a future task. Then the Promise is being queued to run-in the microtask queue immediately after this current task.
programming
And finally, the last console log gets executed right away. So even though the setTimeout callback was queued up before the Promise, the Promise still gets executed first because of the priority of the microtask queue. So now that you know how the event loop works, we can start looking at Promises. 1st, I'll show you how a Promise based API might be consumed. And then we'll look at how we actually create our own Promises from scratch. So fetch is a browser based API, but it's also available on Node via the Node Fetch library. And it allows us to hit an HTTP endpoint and have the response returned to us as a Promise of the response. Fetching data from a remote server is always going to be async, So we can queue up the Promise, then provide it with a callback to map it to JSON. The great thing about Promises is that we can chain them together. Mapping to JSON is also a Promise, so we can return that Promise from the original then callback.
And then in the next one, we'll have the actual user data as a plain JavaScript object. If we go ahead and run this code, you'll see it runs our console log first and then it retrieves the data from the API and console logs that afterwards. The great thing about promises is that you can catch all errors in the chain with a single function.
programming
We can do this by adding catch to the bottom of our promise chain And it will handle errors that happen anywhere within our asynchronous code. If this code were callback based, we'd have to have a separate error handler for every single one of the asynchronous operations. Ends. So if an error is thrown anywhere in our code, it's going to bypass all of the future then callbacks and go straight to the catch callback.
When you start creating promises, that's when you're more likely to screw things up. 1st, I'm setting up a log function, so I can show you the elapsed time between each line of code. Up a while loop that loops a 1,000,000,000 times arbitrarily. If we run this on the main thread, it's going to block all of their code from executing until the 1,000,000,000 loops are done. So we'll do one console log, run our while loop, and then do another console log after that.
programming
And you can see it takes about 700 milliseconds to finish the while loop.
Our script is essentially frozen until that while loop is complete. So let's go ahead and wrap this code in a Promise, so we can get it off the main thread and execute it as a micro task. This is one tricky little way you might screw things up. So we create a new Promise, we add our code inside that Promise, and then we have it resolved to that value when done.
programming
So you might think that because we're wrapping this in a Promise that we're going to execute this off the main thread. But the actual creation of the Promise and that big while loop is still happening on the main thread. It's only the resolving of the value that happens as a microtask. So the first synchronous line gets logged right away And the second one should too, but there's still a 700 millisecond delay because that while loop is still blocking on the main thread.
So to ensure that all of our synchronous code runs as fast as possible, we'll refactor our code once again to say promise resolve, then we'll run the while loop inside of that resolvePromises callback. By putting this code inside of a resolve Promise, we can be guaranteed that it will be executed after all of the synchronous code in the current macro task has completed.
programming
If we go ahead and run our script again, you can see we get our 2 console logs right away and then finally the promise resolves after 700 milliseconds. So now that you know all that stuff, you should be in the clear to use asyncawait responsibly. We already know that promises are a huge improvement over callbacks, but promises can still be really hard to read and follow, especially when you have a long chain of multiple asynchronous events. AsyncAwait really just boils down to syntactic Sugar to make your asynchronous code read like synchronous code. First, let's look at the async part of the equation and see what that does. Here we have a regular function that does nothing. And if we put the async keyword in front of it, we have a function that returns a promise of nothing. So whatever gets returned inside this function will be a Promise of that value. I'm going to reuse this GetFruit function throughout the lesson just to simulate what a Promise based API looks like. In this case, the user can pass in the name of a fruit and then the function will resolve to the value of the fruit emoji from this object. And just to make this a little more clear, if we didn't use the async keyword, we could write this function by just returning a Promise that resolves to this value. So when you use the async keyword, the magic that happens is that it takes the return value and automatically resolves it as a Promise. But that's not everything that it does. It also sets up a context for you to use the await keyword. The real power of an async function comes when you combine it with the await keyword to pause the execution of the function. Now, I'm going to write a second async function called make smoothie. What we need to do is get multiple fruits and then combine them together as a single value. Instead of chaining together a bunch of then callbacks, we can just have a Promise resolved to the value of a variable. Await is like saying pause the execution of this function until the GetFruit Promise resolves to a value, at which point we and use it as the variable a.
And then we'll move on to the next line of code. After we get a pineapple, we can then get a strawberry and then we'll return them together as an array. One of the most annoying things with Promises is that it's kind of difficult to share resolved values between multiple steps in the Promise chain.
candy
But AsyncAwait solves this problem really nicely. The code on the right is what this would look like if we wrote it with just regular promises. And as you can see, there's a lot more code and a lot complexity there. Now if you're already a JavaScript expert, then I'm kind of trolling you because you know that the code on the left is making the single biggest mistake that people make when using asyncawait, And that is failing to run the code concurrently.
If we go back to the code on the left, you can see that we're waiting for a pineapple to resolve and then we're getting a strawberry afterwards. But we could get both of these things at the same time. You really only need to await one thing after the other if the second value is dependent on the first value. For example, if you need to get a user ID before you can then retrieve some data from the database. Let's imagine we're making these calls from a remote API and there's about a second of latency. If we run this code again with a delay, you can see it takes a full second to get the 1st fruit and then a full second to get the 2nd fruit.
fruits
data management
databases
programming
data
But the whole point of the event loop is to avoid blocking code like this. So we know that an async function always returns a Promise. So instead of doing one after the other, we can add both of our Promises to Promise dot all. This will tell all the promises in the array to run concurrently and then have the resolved values be at that index in the array. So this is something that you should always be thinking about when working with async functions. You don't want to accidentally pause a function unnecessarily. So instead of awaiting a whole bunch of individual promises, you might want to add all your promises to an array and then await that Promise.
All call. And as you can see here, we've doubled the speed of the original function. Another nice benefit of asyncawait is error handling. Instead of chaining a catch callback to our Promise chain, we can just wrap our code in a try catch block. This offers much better flexibility when handling errors that might occur across multiple If we take our code from the last example and throw an error in the middle of it, we can then catch that error down here in the Catch block. The first thing we'll probably wanna do here is console log the error.
programming
And then we can either catch the error and throw another error or we can catch the error and return a value. Your decision here will dictate the control flow for the consumer of this Promise. If you return a value, it's basically like ignoring the error and then providing some replacement value.
So the consumer of the promise won't get an error, but instead they'll get the resolved value inside of the then callback. In contrast, if we throw an error inside of our catch block, It will break the consumer's promise chain and be handled by their catch callback. Now I wanna show you a couple of tricks to make your code as sweet as possible. Let's imagine we have a string of ids, and then we want to retrieve all these ids from the database. We can use array map to convert them to an array if promises and then resolve them all concurrently using Promise dot all.
programming
logic
databases
That looks great, but you need to be careful when using async await in a map or foreach loop because it won't actually pause the function in this context. So normally, we would expect this loop to stop if we do await getFruit, but that's actually not what happens in this case. Instead, it will run all these promises concurrently, so that might not be the behavior that you're expecting. If you want to run a loop and have every iteration In that loop, a way to promise, you need to use a traditional for loop. So you can write async functions and then write a for loop inside that function then use the await keyword inside the loop. When you write your code like this it will pause each step of the loop until that promise is resolved. But more often than not you'll probably want to run everything concurrently and a cool thing you can do is use the await keyword directly in a for loop. If you have a Promise that you know resolves to an array, you can actually just use the await keyword directly in your loop. So you can say 'for await' in your code which will await The array of items to resolve and then loop over them immediately after. And as you can probably imagine, you can also use the await keyword directly in your conditionals. On the left side of the conditional, we can await the result value from a Promise and then we can see if it's equal to some other value. So that gives you a super concise way to write conditional expressions when working with Promises. Hopefully, that gives you some ideas on what you can do with async await in ES 7 or TypeScript. It is truly one of the sweetest things to ever happen to JavaScript. If this video helped you, please like and subscribe and make sure to join the live next week for the t shirt giveaway.
And if you want to take your development to the next level consider becoming a pro member at angularfirebase.com. You'll get access to all kinds of advanced content designed to help you build and ship your app faster. Thanks for watching and I'll talk to you soon.
software development
software
JavaScript is a single threaded programming language yet everything we do on the web tends to be blocking or time consuming, which means that asynchronous programming is an essential skill for any JavaScript developer. Today's video will focus primarily on the amazing syntactic sugar provided by AsyncAwait, but before we can get there we really need to understand Things from the ground up starting with the browser or Node. Js event loop, callbacks, promises, and then finally async await. And we're going to do this without making a single joke about a sink or a weight. If you're new here, like and subscribe and we'll be giving away another one of a kind t shirt with this video. All you to do is leave a comment below and we'll pick a random winner next week. In order to understand anything async, you really need to first understand the event loop. This this is Ace. I hope that clears up any questions you have. I'm going to give you the general overview, but I highly recommend you watch this talk from Jake Archibald, which is the best of the event loop that I've ever seen. Then after you're done watching that talk you should check out Steven Fluin's demos with Angular channel which just released a video about callbacks which are one of the that happen within the event loop. So what is the event loop and what does it have to do with async await? Both the browser and Node. Js are always running threaded event loop to run your code. On the first go around, it will run all of your synchronous code, but it might also queue up asynchronous events to be called back later. You say, here's a function that I need to run, but first, I need to go get some data from the network. The event loop says, okay, I'll keep doing my thing while you do your thing in a separate thread pool. Then at some point in the future, gitData will finish and let the event loop know that it's ready to be called back. Now this is where things get interesting. If it's a macro task, like a setTime out or setInterval, it will be executed on the next event loop. But if it's a microtask, like a fulfilled Promise, then it will be called back before the start of the next event loop. Let's look at the implications of this by writing some actual code. First, we will write a console log which is synchronous. Then we'll throw in a setTimeout, but give it a time delay of 0 milliseconds. Then we'll have a promise that resolves right away. And lastly, we will add another console log for one more synchronous line of code. So nothing here has any actual time delay. So intuitively, I would think that each line of code would be executed 1 by 1. But that's not how things work in the event loop. If we execute this code, you can see the first line gets logged right away because it's running on the main thread. Then if we run the second line, it's being queued for a future task. Then the Promise is being queued to run-in the microtask queue immediately after this current task. And finally, the last console log gets executed right away. So even though the setTimeout callback was queued up before the Promise, the Promise still gets executed first because of the priority of the microtask queue. So now that you know how the event loop works, we can start looking at Promises. 1st, I'll show you how a Promise based API might be consumed. And then we'll look at how we actually create our own Promises from scratch. So fetch is a browser based API, but it's also available on Node via the Node Fetch library. And it allows us to hit an HTTP endpoint and have the response returned to us as a Promise of the response. Fetching data from a remote server is always going to be async, So we can queue up the Promise, then provide it with a callback to map it to JSON. The great thing about Promises is that we can chain them together. Mapping to JSON is also a Promise, so we can return that Promise from the original then callback. And then in the next one, we'll have the actual user data as a plain JavaScript object. If we go ahead and run this code, you'll see it runs our console log first and then it retrieves the data from the API and console logs that afterwards. The great thing about promises is that you can catch all errors in the chain with a single function. We can do this by adding catch to the bottom of our promise chain And it will handle errors that happen anywhere within our asynchronous code. If this code were callback based, we'd have to have a separate error handler for every single one of the asynchronous operations. Ends. So if an error is thrown anywhere in our code, it's going to bypass all of the future then callbacks and go straight to the catch callback. When you start creating promises, that's when you're more likely to screw things up. 1st, I'm setting up a log function, so I can show you the elapsed time between each line of code. Up a while loop that loops a 1,000,000,000 times arbitrarily. If we run this on the main thread, it's going to block all of their code from executing until the 1,000,000,000 loops are done. So we'll do one console log, run our while loop, and then do another console log after that. And you can see it takes about 700 milliseconds to finish the while loop. Our script is essentially frozen until that while loop is complete. So let's go ahead and wrap this code in a Promise, so we can get it off the main thread and execute it as a micro task. This is one tricky little way you might screw things up. So we create a new Promise, we add our code inside that Promise, and then we have it resolved to that value when done. So you might think that because we're wrapping this in a Promise that we're going to execute this off the main thread. But the actual creation of the Promise and that big while loop is still happening on the main thread. It's only the resolving of the value that happens as a microtask. So the first synchronous line gets logged right away And the second one should too, but there's still a 700 millisecond delay because that while loop is still blocking on the main thread. So to ensure that all of our synchronous code runs as fast as possible, we'll refactor our code once again to say promise resolve, then we'll run the while loop inside of that resolvePromises callback. By putting this code inside of a resolve Promise, we can be guaranteed that it will be executed after all of the synchronous code in the current macro task has completed. If we go ahead and run our script again, you can see we get our 2 console logs right away and then finally the promise resolves after 700 milliseconds. So now that you know all that stuff, you should be in the clear to use asyncawait responsibly. We already know that promises are a huge improvement over callbacks, but promises can still be really hard to read and follow, especially when you have a long chain of multiple asynchronous events. AsyncAwait really just boils down to syntactic Sugar to make your asynchronous code read like synchronous code. First, let's look at the async part of the equation and see what that does. Here we have a regular function that does nothing. And if we put the async keyword in front of it, we have a function that returns a promise of nothing. So whatever gets returned inside this function will be a Promise of that value. I'm going to reuse this GetFruit function throughout the lesson just to simulate what a Promise based API looks like. In this case, the user can pass in the name of a fruit and then the function will resolve to the value of the fruit emoji from this object. And just to make this a little more clear, if we didn't use the async keyword, we could write this function by just returning a Promise that resolves to this value. So when you use the async keyword, the magic that happens is that it takes the return value and automatically resolves it as a Promise. But that's not everything that it does. It also sets up a context for you to use the await keyword. The real power of an async function comes when you combine it with the await keyword to pause the execution of the function. Now, I'm going to write a second async function called make smoothie. What we need to do is get multiple fruits and then combine them together as a single value. Instead of chaining together a bunch of then callbacks, we can just have a Promise resolved to the value of a variable. Await is like saying pause the execution of this function until the GetFruit Promise resolves to a value, at which point we and use it as the variable a. And then we'll move on to the next line of code. After we get a pineapple, we can then get a strawberry and then we'll return them together as an array. One of the most annoying things with Promises is that it's kind of difficult to share resolved values between multiple steps in the Promise chain. But AsyncAwait solves this problem really nicely. The code on the right is what this would look like if we wrote it with just regular promises. And as you can see, there's a lot more code and a lot complexity there. Now if you're already a JavaScript expert, then I'm kind of trolling you because you know that the code on the left is making the single biggest mistake that people make when using asyncawait, And that is failing to run the code concurrently. If we go back to the code on the left, you can see that we're waiting for a pineapple to resolve and then we're getting a strawberry afterwards. But we could get both of these things at the same time. You really only need to await one thing after the other if the second value is dependent on the first value. For example, if you need to get a user ID before you can then retrieve some data from the database. Let's imagine we're making these calls from a remote API and there's about a second of latency. If we run this code again with a delay, you can see it takes a full second to get the 1st fruit and then a full second to get the 2nd fruit. But the whole point of the event loop is to avoid blocking code like this. So we know that an async function always returns a Promise. So instead of doing one after the other, we can add both of our Promises to Promise dot all. This will tell all the promises in the array to run concurrently and then have the resolved values be at that index in the array. So this is something that you should always be thinking about when working with async functions. You don't want to accidentally pause a function unnecessarily. So instead of awaiting a whole bunch of individual promises, you might want to add all your promises to an array and then await that Promise. All call. And as you can see here, we've doubled the speed of the original function. Another nice benefit of asyncawait is error handling. Instead of chaining a catch callback to our Promise chain, we can just wrap our code in a try catch block. This offers much better flexibility when handling errors that might occur across multiple If we take our code from the last example and throw an error in the middle of it, we can then catch that error down here in the Catch block. The first thing we'll probably wanna do here is console log the error. And then we can either catch the error and throw another error or we can catch the error and return a value. Your decision here will dictate the control flow for the consumer of this Promise. If you return a value, it's basically like ignoring the error and then providing some replacement value. So the consumer of the promise won't get an error, but instead they'll get the resolved value inside of the then callback. In contrast, if we throw an error inside of our catch block, It will break the consumer's promise chain and be handled by their catch callback. Now I wanna show you a couple of tricks to make your code as sweet as possible. Let's imagine we have a string of ids, and then we want to retrieve all these ids from the database. We can use array map to convert them to an array if promises and then resolve them all concurrently using Promise dot all. That looks great, but you need to be careful when using async await in a map or foreach loop because it won't actually pause the function in this context. So normally, we would expect this loop to stop if we do await getFruit, but that's actually not what happens in this case. Instead, it will run all these promises concurrently, so that might not be the behavior that you're expecting. If you want to run a loop and have every iteration In that loop, a way to promise, you need to use a traditional for loop. So you can write async functions and then write a for loop inside that function then use the await keyword inside the loop. When you write your code like this it will pause each step of the loop until that promise is resolved. But more often than not you'll probably want to run everything concurrently and a cool thing you can do is use the await keyword directly in a for loop. If you have a Promise that you know resolves to an array, you can actually just use the await keyword directly in your loop. So you can say 'for await' in your code which will await The array of items to resolve and then loop over them immediately after. And as you can probably imagine, you can also use the await keyword directly in your conditionals. On the left side of the conditional, we can await the result value from a Promise and then we can see if it's equal to some other value. So that gives you a super concise way to write conditional expressions when working with Promises. Hopefully, that gives you some ideas on what you can do with async await in ES 7 or TypeScript. It is truly one of the sweetest things to ever happen to JavaScript. If this video helped you, please like and subscribe and make sure to join the live next week for the t shirt giveaway. And if you want to take your development to the next level consider becoming a pro member at angularfirebase.com. You'll get access to all kinds of advanced content designed to help you build and ship your app faster. Thanks for watching and I'll talk to you soon.
JavaScript
javascript
is
is
a
a
single
single
threaded
threaded
programming
programming
language
language
yet
yet
everything
everything
we
we
do
do
on
on
the
the
web
web
tends
tends
to
to
be
be
blocking
blocking
or
or
time
time
consuming,
consuming
which
which
means
means
that
that
asynchronous
asynchronous
programming
programming
is
is
an
an
essential
essential
skill
skill
for
for
any
any
JavaScript
javascript
developer.
developer
Today's
today's
video
video
will
will
focus
focus
primarily
primarily
on
on
the
the
amazing
amazing
syntactic
syntactic
sugar
sugar
provided
provided
by
by
AsyncAwait,
asyncawait
but
but
before
before
we
we
can
can
get
get
there
there
we
we
really
really
need
need
to
to
understand
understand
Things
things
from
from
the
the
ground
ground
up
up
starting
starting
with
with
the
the
browser
browser
or
or
Node.
node
Js
js
event
event
loop,
loop
callbacks,
callbacks
promises,
promises
and
and
then
then
finally
finally
async
async
await.
await
And
and
we're
we're
going
going
to
to
do
do
this
this
without
without
making
making
a
a
single
single
joke
joke
about
about
a
a
sink
sink
or
or
a
a
weight.
weight
If
if
you're
you're
new
new
here,
here
like
like
and
and
subscribe
subscribe
and
and
we'll
we'll
be
be
giving
giving
away
away
another
another
one
one
of
of
a
a
kind
kind
t
t
shirt
shirt
with
with
this
this
video.
video
All
all
you
you
to
to
do
do
is
is
leave
leave
a
a
comment
comment
below
below
and
and
we'll
we'll
pick
pick
a
a
random
random
winner
winner
next
next
week.
week
In
in
order
order
to
to
understand
understand
anything
anything
async,
async
you
you
really
really
need
need
to
to
first
first
understand
understand
the
the
event
event
loop.
loop
This
this
this
this
is
is
Ace.
ace
I
i
hope
hope
that
that
clears
clears
up
up
any
any
questions
questions
you
you
have.
have
I'm
i'm
going
going
to
to
give
give
you
you
the
the
general
general
overview,
overview
but
but
I
i
highly
highly
recommend
recommend
you
you
watch
watch
this
this
talk
talk
from
from
Jake
jake
Archibald,
archibald
which
which
is
is
the
the
best
best
of
of
the
the
event
event
loop
loop
that
that
I've
i've
ever
ever
seen.
seen
Then
then
after
after
you're
you're
done
done
watching
watching
that
that
talk
talk
you
you
should
should
check
check
out
out
Steven
steven
Fluin's
fluin's
demos
demos
with
with
Angular
angular
channel
channel
which
which
just
just
released
released
a
a
video
video
about
about
callbacks
callbacks
which
which
are
are
one
one
of
of
the
the
that
that
happen
happen
within
within
the
the
event
event
loop.
loop
So
so
what
what
is
is
the
the
event
event
loop
loop
and
and
what
what
does
does
it
it
have
have
to
to
do
do
with
with
async
async
await?
await
Both
both
the
the
browser
browser
and
and
Node.
node
Js
js
are
are
always
always
running
running
threaded
threaded
event
event
loop
loop
to
to
run
run
your
your
code.
code
On
on
the
the
first
first
go
go
around,
around
it
it
will
will
run
run
all
all
of
of
your
your
synchronous
synchronous
code,
code
but
but
it
it
might
might
also
also
queue
queue
up
up
asynchronous
asynchronous
events
events
to
to
be
be
called
called
back
back
later.
later
You
you
say,
say
here's
here's
a
a
function
function
that
that
I
i
need
need
to
to
run,
run
but
but
first,
first
I
i
need
need
to
to
go
go
get
get
some
some
data
data
from
from
the
the
network.
network
The
the
event
event
loop
loop
says,
says
okay,
okay
I'll
i'll
keep
keep
doing
doing
my
my
thing
thing
while
while
you
you
do
do
your
your
thing
thing
in
in
a
a
separate
separate
thread
thread
pool.
pool
Then
then
at
at
some
some
point
point
in
in
the
the
future,
future
gitData
gitdata
will
will
finish
finish
and
and
let
let
the
the
event
event
loop
loop
know
know
that
that
it's
it's
ready
ready
to
to
be
be
called
called
back.
back
Now
now
this
this
is
is
where
where
things
things
get
get
interesting.
interesting
If
if
it's
it's
a
a
macro
macro
task,
task
like
like
a
a
setTime
settime
out
out
or
or
setInterval,
setinterval
it
it
will
will
be
be
executed
executed
on
on
the
the
next
next
event
event
loop.
loop
But
but
if
if
it's
it's
a
a
microtask,
microtask
like
like
a
a
fulfilled
fulfilled
Promise,
promise
then
then
it
it
will
will
be
be
called
called
back
back
before
before
the
the
start
start
of
of
the
the
next
next
event
event
loop.
loop
Let's
let's
look
look
at
at
the
the
implications
implications
of
of
this
this
by
by
writing
writing
some
some
actual
actual
code.
code
First,
first
we
we
will
will
write
write
a
a
console
console
log
log
which
which
is
is
synchronous.
synchronous
Then
then
we'll
we'll
throw
throw
in
in
a
a
setTimeout,
settimeout
but
but
give
give
it
it
a
a
time
time
delay
delay
of
of
0
0
milliseconds.
milliseconds
Then
then
we'll
we'll
have
have
a
a
promise
promise
that
that
resolves
resolves
right
right
away.
away
And
and
lastly,
lastly
we
we
will
will
add
add
another
another
console
console
log
log
for
for
one
one
more
more
synchronous
synchronous
line
line
of
of
code.
code
So
so
nothing
nothing
here
here
has
has
any
any
actual
actual
time
time
delay.
delay
So
so
intuitively,
intuitively
I
i
would
would
think
think
that
that
each
each
line
line
of
of
code
code
would
would
be
be
executed
executed
1
1
by
by
1.
1
But
but
that's
that's
not
not
how
how
things
things
work
work
in
in
the
the
event
event
loop.
loop
If
if
we
we
execute
execute
this
this
code,
code
you
you
can
can
see
see
the
the
first
first
line
line
gets
gets
logged
logged
right
right
away
away
because
because
it's
it's
running
running
on
on
the
the
main
main
thread.
thread
Then
then
if
if
we
we
run
run
the
the
second
second
line,
line
it's
it's
being
being
queued
queued
for
for
a
a
future
future
task.
task
Then
then
the
the
Promise
promise
is
is
being
being
queued
queued
to
to
run-in
run-in
the
the
microtask
microtask
queue
queue
immediately
immediately
after
after
this
this
current
current
task.
task
And
and
finally,
finally
the
the
last
last
console
console
log
log
gets
gets
executed
executed
right
right
away.
away
So
so
even
even
though
though
the
the
setTimeout
settimeout
callback
callback
was
was
queued
queued
up
up
before
before
the
the
Promise,
promise
the
the
Promise
promise
still
still
gets
gets
executed
executed
first
first
because
because
of
of
the
the
priority
priority
of
of
the
the
microtask
microtask
queue.
queue
So
so
now
now
that
that
you
you
know
know
how
how
the
the
event
event
loop
loop
works,
works
we
we
can
can
start
start
looking
looking
at
at
Promises.
promises
1st,
1st
I'll
i'll
show
show
you
you
how
how
a
a
Promise
promise
based
based
API
api
might
might
be
be
consumed.
consumed
And
and
then
then
we'll
we'll
look
look
at
at
how
how
we
we
actually
actually
create
create
our
our
own
own
Promises
promises
from
from
scratch.
scratch
So
so
fetch
fetch
is
is
a
a
browser
browser
based
based
API,
api
but
but
it's
it's
also
also
available
available
on
on
Node
node
via
via
the
the
Node
node
Fetch
fetch
library.
library
And
and
it
it
allows
allows
us
us
to
to
hit
hit
an
an
HTTP
http
endpoint
endpoint
and
and
have
have
the
the
response
response
returned
returned
to
to
us
us
as
as
a
a
Promise
promise
of
of
the
the
response.
response
Fetching
fetching
data
data
from
from
a
a
remote
remote
server
server
is
is
always
always
going
going
to
to
be
be
async,
async
So
so
we
we
can
can
queue
queue
up
up
the
the
Promise,
promise
then
then
provide
provide
it
it
with
with
a
a
callback
callback
to
to
map
map
it
it
to
to
JSON.
json
The
the
great
great
thing
thing
about
about
Promises
promises
is
is
that
that
we
we
can
can
chain
chain
them
them
together.
together
Mapping
mapping
to
to
JSON
json
is
is
also
also
a
a
Promise,
promise
so
so
we
we
can
can
return
return
that
that
Promise
promise
from
from
the
the
original
original
then
then
callback.
callback
And
and
then
then
in
in
the
the
next
next
one,
one
we'll
we'll
have
have
the
the
actual
actual
user
user
data
data
as
as
a
a
plain
plain
JavaScript
javascript
object.
object
If
if
we
we
go
go
ahead
ahead
and
and
run
run
this
this
code,
code
you'll
you'll
see
see
it
it
runs
runs
our
our
console
console
log
log
first
first
and
and
then
then
it
it
retrieves
retrieves
the
the
data
data
from
from
the
the
API
api
and
and
console
console
logs
logs
that
that
afterwards.
afterwards
The
the
great
great
thing
thing
about
about
promises
promises
is
is
that
that
you
you
can
can
catch
catch
all
all
errors
errors
in
in
the
the
chain
chain
with
with
a
a
single
single
function.
function
We
we
can
can
do
do
this
this
by
by
adding
adding
catch
catch
to
to
the
the
bottom
bottom
of
of
our
our
promise
promise
chain
chain
And
and
it
it
will
will
handle
handle
errors
errors
that
that
happen
happen
anywhere
anywhere
within
within
our
our
asynchronous
asynchronous
code.
code
If
if
this
this
code
code
were
were
callback
callback
based,
based
we'd
we'd
have
have
to
to
have
have
a
a
separate
separate
error
error
handler
handler
for
for
every
every
single
single
one
one
of
of
the
the
asynchronous
asynchronous
operations.
operations
Ends.
ends
So
so
if
if
an
an
error
error
is
is
thrown
thrown
anywhere
anywhere
in
in
our
our
code,
code
it's
it's
going
going
to
to
bypass
bypass
all
all
of
of
the
the
future
future
then
then
callbacks
callbacks
and
and
go
go
straight
straight
to
to
the
the
catch
catch
callback.
callback
When
when
you
you
start
start
creating
creating
promises,
promises
that's
that's
when
when
you're
you're
more
more
likely
likely
to
to
screw
screw
things
things
up.
up
1st,
1st
I'm
i'm
setting
setting
up
up
a
a
log
log
function,
function
so
so
I
i
can
can
show
show
you
you
the
the
elapsed
elapsed
time
time
between
between
each
each
line
line
of
of
code.
code
Up
up
a
a
while
while
loop
loop
that
that
loops
loops
a
a
1,000,000,000
1,000,000,000
times
times
arbitrarily.
arbitrarily
If
if
we
we
run
run
this
this
on
on
the
the
main
main
thread,
thread
it's
it's
going
going
to
to
block
block
all
all
of
of
their
their
code
code
from
from
executing
executing
until
until
the
the
1,000,000,000
1,000,000,000
loops
loops
are
are
done.
done
So
so
we'll
we'll
do
do
one
one
console
console
log,
log
run
run
our
our
while
while
loop,
loop
and
and
then
then
do
do
another
another
console
console
log
log
after
after
that.
that
And
and
you
you
can
can
see
see
it
it
takes
takes
about
about
700
700
milliseconds
milliseconds
to
to
finish
finish
the
the
while
while
loop.
loop
Our
our
script
script
is
is
essentially
essentially
frozen
frozen
until
until
that
that
while
while
loop
loop
is
is
complete.
complete
So
so
let's
let's
go
go
ahead
ahead
and
and
wrap
wrap
this
this
code
code
in
in
a
a
Promise,
promise
so
so
we
we
can
can
get
get
it
it
off
off
the
the
main
main
thread
thread
and
and
execute
execute
it
it
as
as
a
a
micro
micro
task.
task
This
this
is
is
one
one
tricky
tricky
little
little
way
way
you
you
might
might
screw
screw
things
things
up.
up
So
so
we
we
create
create
a
a
new
new
Promise,
promise
we
we
add
add
our
our
code
code
inside
inside
that
that
Promise,
promise
and
and
then
then
we
we
have
have
it
it
resolved
resolved
to
to
that
that
value
value
when
when
done.
done
So
so
you
you
might
might
think
think
that
that
because
because
we're
we're
wrapping
wrapping
this
this
in
in
a
a
Promise
promise
that
that
we're
we're
going
going
to
to
execute
execute
this
this
off
off
the
the
main
main
thread.
thread
But
but
the
the
actual
actual
creation
creation
of
of
the
the
Promise
promise
and
and
that
that
big
big
while
while
loop
loop
is
is
still
still
happening
happening
on
on
the
the
main
main
thread.
thread
It's
it's
only
only
the
the
resolving
resolving
of
of
the
the
value
value
that
that
happens
happens
as
as
a
a
microtask.
microtask
So
so
the
the
first
first
synchronous
synchronous
line
line
gets
gets
logged
logged
right
right
away
away
And
and
the
the
second
second
one
one
should
should
too,
too
but
but
there's
there's
still
still
a
a
700
700
millisecond
millisecond
delay
delay
because
because
that
that
while
while
loop
loop
is
is
still
still
blocking
blocking
on
on
the
the
main
main
thread.
thread
So
so
to
to
ensure
ensure
that
that
all
all
of
of
our
our
synchronous
synchronous
code
code
runs
runs
as
as
fast
fast
as
as
possible,
possible
we'll
we'll
refactor
refactor
our
our
code
code
once
once
again
again
to
to
say
say
promise
promise
resolve,
resolve
then
then
we'll
we'll
run
run
the
the
while
while
loop
loop
inside
inside
of
of
that
that
resolvePromises
resolvepromises
callback.
callback
By
by
putting
putting
this
this
code
code
inside
inside
of
of
a
a
resolve
resolve
Promise,
promise
we
we
can
can
be
be
guaranteed
guaranteed
that
that
it
it
will
will
be
be
executed
executed
after
after
all
all
of
of
the
the
synchronous
synchronous
code
code
in
in
the
the
current
current
macro
macro
task
task
has
has
completed.
completed
If
if
we
we
go
go
ahead
ahead
and
and
run
run
our
our
script
script
again,
again
you
you
can
can
see
see
we
we
get
get
our
our
2
2
console
console
logs
logs
right
right
away
away
and
and
then
then
finally
finally
the
the
promise
promise
resolves
resolves
after
after
700
700
milliseconds.
milliseconds
So
so
now
now
that
that
you
you
know
know
all
all
that
that
stuff,
stuff
you
you
should
should
be
be
in
in
the
the
clear
clear
to
to
use
use
asyncawait
asyncawait
responsibly.
responsibly
We
we
already
already
know
know
that
that
promises
promises
are
are
a
a
huge
huge
improvement
improvement
over
over
callbacks,
callbacks
but
but
promises
promises
can
can
still
still
be
be
really
really
hard
hard
to
to
read
read
and
and
follow,
follow
especially
especially
when
when
you
you
have
have
a
a
long
long
chain
chain
of
of
multiple
multiple
asynchronous
asynchronous
events.
events
AsyncAwait
asyncawait
really
really
just
just
boils
boils
down
down
to
to
syntactic
syntactic
Sugar
sugar
to
to
make
make
your
your
asynchronous
asynchronous
code
code
read
read
like
like
synchronous
synchronous
code.
code
First,
first
let's
let's
look
look
at
at
the
the
async
async
part
part
of
of
the
the
equation
equation
and
and
see
see
what
what
that
that
does.
does
Here
here
we
we
have
have
a
a
regular
regular
function
function
that
that
does
does
nothing.
nothing
And
and
if
if
we
we
put
put
the
the
async
async
keyword
keyword
in
in
front
front
of
of
it,
it
we
we
have
have
a
a
function
function
that
that
returns
returns
a
a
promise
promise
of
of
nothing.
nothing
So
so
whatever
whatever
gets
gets
returned
returned
inside
inside
this
this
function
function
will
will
be
be
a
a
Promise
promise
of
of
that
that
value.
value
I'm
i'm
going
going
to
to
reuse
reuse
this
this
GetFruit
getfruit
function
function
throughout
throughout
the
the
lesson
lesson
just
just
to
to
simulate
simulate
what
what
a
a
Promise
promise
based
based
API
api
looks
looks
like.
like
In
in
this
this
case,
case
the
the
user
user
can
can
pass
pass
in
in
the
the
name
name
of
of
a
a
fruit
fruit
and
and
then
then
the
the
function
function
will
will
resolve
resolve
to
to
the
the
value
value
of
of
the
the
fruit
fruit
emoji
emoji
from
from
this
this
object.
object
And
and
just
just
to
to
make
make
this
this
a
a
little
little
more
more
clear,
clear
if
if
we
we
didn't
didn't
use
use
the
the
async
async
keyword,
keyword
we
we
could
could
write
write
this
this
function
function
by
by
just
just
returning
returning
a
a
Promise
promise
that
that
resolves
resolves
to
to
this
this
value.
value
So
so
when
when
you
you
use
use
the
the
async
async
keyword,
keyword
the
the
magic
magic
that
that
happens
happens
is
is
that
that
it
it
takes
takes
the
the
return
return
value
value
and
and
automatically
automatically
resolves
resolves
it
it
as
as
a
a
Promise.
promise
But
but
that's
that's
not
not
everything
everything
that
that
it
it
does.
does
It
it
also
also
sets
sets
up
up
a
a
context
context
for
for
you
you
to
to
use
use
the
the
await
await
keyword.
keyword
The
the
real
real
power
power
of
of
an
an
async
async
function
function
comes
comes
when
when
you
you
combine
combine
it
it
with
with
the
the
await
await
keyword
keyword
to
to
pause
pause
the
the
execution
execution
of
of
the
the
function.
function
Now,
now
I'm
i'm
going
going
to
to
write
write
a
a
second
second
async
async
function
function
called
called
make
make
smoothie.
smoothie
What
what
we
we
need
need
to
to
do
do
is
is
get
get
multiple
multiple
fruits
fruits
and
and
then
then
combine
combine
them
them
together
together
as
as
a
a
single
single
value.
value
Instead
instead
of
of
chaining
chaining
together
together
a
a
bunch
bunch
of
of
then
then
callbacks,
callbacks
we
we
can
can
just
just
have
have
a
a
Promise
promise
resolved
resolved
to
to
the
the
value
value
of
of
a
a
variable.
variable
Await
await
is
is
like
like
saying
saying
pause
pause
the
the
execution
execution
of
of
this
this
function
function
until
until
the
the
GetFruit
getfruit
Promise
promise
resolves
resolves
to
to
a
a
value,
value
at
at
which
which
point
point
we
we
and
and
use
use
it
it
as
as
the
the
variable
variable
a.
a
And
and
then
then
we'll
we'll
move
move
on
on
to
to
the
the
next
next
line
line
of
of
code.
code
After
after
we
we
get
get
a
a
pineapple,
pineapple
we
we
can
can
then
then
get
get
a
a
strawberry
strawberry
and
and
then
then
we'll
we'll
return
return
them
them
together
together
as
as
an
an
array.
array
One
one
of
of
the
the
most
most
annoying
annoying
things
things
with
with
Promises
promises
is
is
that
that
it's
it's
kind
kind
of
of
difficult
difficult
to
to
share
share
resolved
resolved
values
values
between
between
multiple
multiple
steps
steps
in
in
the
the
Promise
promise
chain.
chain
But
but
AsyncAwait
asyncawait
solves
solves
this
this
problem
problem
really
really
nicely.
nicely
The
the
code
code
on
on
the
the
right
right
is
is
what
what
this
this
would
would
look
look
like
like
if
if
we
we
wrote
wrote
it
it
with
with
just
just
regular
regular
promises.
promises
And
and
as
as
you
you
can
can
see,
see
there's
there's
a
a
lot
lot
more
more
code
code
and
and
a
a
lot
lot
complexity
complexity
there.
there
Now
now
if
if
you're
you're
already
already
a
a
JavaScript
javascript
expert,
expert
then
then
I'm
i'm
kind
kind
of
of
trolling
trolling
you
you
because
because
you
you
know
know
that
that
the
the
code
code
on
on
the
the
left
left
is
is
making
making
the
the
single
single
biggest
biggest
mistake
mistake
that
that
people
people
make
make
when
when
using
using
asyncawait,
asyncawait
And
and
that
that
is
is
failing
failing
to
to
run
run
the
the
code
code
concurrently.
concurrently
If
if
we
we
go
go
back
back
to
to
the
the
code
code
on
on
the
the
left,
left
you
you
can
can
see
see
that
that
we're
we're
waiting
waiting
for
for
a
a
pineapple
pineapple
to
to
resolve
resolve
and
and
then
then
we're
we're
getting
getting
a
a
strawberry
strawberry
afterwards.
afterwards
But
but
we
we
could
could
get
get
both
both
of
of
these
these
things
things
at
at
the
the
same
same
time.
time
You
you
really
really
only
only
need
need
to
to
await
await
one
one
thing
thing
after
after
the
the
other
other
if
if
the
the
second
second
value
value
is
is
dependent
dependent
on
on
the
the
first
first
value.
value
For
for
example,
example
if
if
you
you
need
need
to
to
get
get
a
a
user
user
ID
id
before
before
you
you
can
can
then
then
retrieve
retrieve
some
some
data
data
from
from
the
the
database.
database
Let's
let's
imagine
imagine
we're
we're
making
making
these
these
calls
calls
from
from
a
a
remote
remote
API
api
and
and
there's
there's
about
about
a
a
second
second
of
of
latency.
latency
If
if
we
we
run
run
this
this
code
code
again
again
with
with
a
a
delay,
delay
you
you
can
can
see
see
it
it
takes
takes
a
a
full
full
second
second
to
to
get
get
the
the
1st
1st
fruit
fruit
and
and
then
then
a
a
full
full
second
second
to
to
get
get
the
the
2nd
2nd
fruit.
fruit
But
but
the
the
whole
whole
point
point
of
of
the
the
event
event
loop
loop
is
is
to
to
avoid
avoid
blocking
blocking
code
code
like
like
this.
this
So
so
we
we
know
know
that
that
an
an
async
async
function
function
always
always
returns
returns
a
a
Promise.
promise
So
so
instead
instead
of
of
doing
doing
one
one
after
after
the
the
other,
other
we
we
can
can
add
add
both
both
of
of
our
our
Promises
promises
to
to
Promise
promise
dot
dot
all.
all
This
this
will
will
tell
tell
all
all
the
the
promises
promises
in
in
the
the
array
array
to
to
run
run
concurrently
concurrently
and
and
then
then
have
have
the
the
resolved
resolved
values
values
be
be
at
at
that
that
index
index
in
in
the
the
array.
array
So
so
this
this
is
is
something
something
that
that
you
you
should
should
always
always
be
be
thinking
thinking
about
about
when
when
working
working
with
with
async
async
functions.
functions
You
you
don't
don't
want
want
to
to
accidentally
accidentally
pause
pause
a
a
function
function
unnecessarily.
unnecessarily
So
so
instead
instead
of
of
awaiting
awaiting
a
a
whole
whole
bunch
bunch
of
of
individual
individual
promises,
promises
you
you
might
might
want
want
to
to
add
add
all
all
your
your
promises
promises
to
to
an
an
array
array
and
and
then
then
await
await
that
that
Promise.
promise
All
all
call.
call
And
and
as
as
you
you
can
can
see
see
here,
here
we've
we've
doubled
doubled
the
the
speed
speed
of
of
the
the
original
original
function.
function
Another
another
nice
nice
benefit
benefit
of
of
asyncawait
asyncawait
is
is
error
error
handling.
handling
Instead
instead
of
of
chaining
chaining
a
a
catch
catch
callback
callback
to
to
our
our
Promise
promise
chain,
chain
we
we
can
can
just
just
wrap
wrap
our
our
code
code
in
in
a
a
try
try
catch
catch
block.
block
This
this
offers
offers
much
much
better
better
flexibility
flexibility
when
when
handling
handling
errors
errors
that
that
might
might
occur
occur
across
across
multiple
multiple
If
if
we
we
take
take
our
our
code
code
from
from
the
the
last
last
example
example
and
and
throw
throw
an
an
error
error
in
in
the
the
middle
middle
of
of
it,
it
we
we
can
can
then
then
catch
catch
that
that
error
error
down
down
here
here
in
in
the
the
Catch
catch
block.
block
The
the
first
first
thing
thing
we'll
we'll
probably
probably
wanna
wanna
do
do
here
here
is
is
console
console
log
log
the
the
error.
error
And
and
then
then
we
we
can
can
either
either
catch
catch
the
the
error
error
and
and
throw
throw
another
another
error
error
or
or
we
we
can
can
catch
catch
the
the
error
error
and
and
return
return
a
a
value.
value
Your
your
decision
decision
here
here
will
will
dictate
dictate
the
the
control
control
flow
flow
for
for
the
the
consumer
consumer
of
of
this
this
Promise.
promise
If
if
you
you
return
return
a
a
value,
value
it's
it's
basically
basically
like
like
ignoring
ignoring
the
the
error
error
and
and
then
then
providing
providing
some
some
replacement
replacement
value.
value
So
so
the
the
consumer
consumer
of
of
the
the
promise
promise
won't
won't
get
get
an
an
error,
error
but
but
instead
instead
they'll
they'll
get
get
the
the
resolved
resolved
value
value
inside
inside
of
of
the
the
then
then
callback.
callback
In
in
contrast,
contrast
if
if
we
we
throw
throw
an
an
error
error
inside
inside
of
of
our
our
catch
catch
block,
block
It
it
will
will
break
break
the
the
consumer's
consumer's
promise
promise
chain
chain
and
and
be
be
handled
handled
by
by
their
their
catch
catch
callback.
callback
Now
now
I
i
wanna
wanna
show
show
you
you
a
a
couple
couple
of
of
tricks
tricks
to
to
make
make
your
your
code
code
as
as
sweet
sweet
as
as
possible.
possible
Let's
let's
imagine
imagine
we
we
have
have
a
a
string
string
of
of
ids,
ids
and
and
then
then
we
we
want
want
to
to
retrieve
retrieve
all
all
these
these
ids
ids
from
from
the
the
database.
database
We
we
can
can
use
use
array
array
map
map
to
to
convert
convert
them
them
to
to
an
an
array
array
if
if
promises
promises
and
and
then
then
resolve
resolve
them
them
all
all
concurrently
concurrently
using
using
Promise
promise
dot
dot
all.
all
That
that
looks
looks
great,
great
but
but
you
you
need
need
to
to
be
be
careful
careful
when
when
using
using
async
async
await
await
in
in
a
a
map
map
or
or
foreach
foreach
loop
loop
because
because
it
it
won't
won't
actually
actually
pause
pause
the
the
function
function
in
in
this
this
context.
context
So
so
normally,
normally
we
we
would
would
expect
expect
this
this
loop
loop
to
to
stop
stop
if
if
we
we
do
do
await
await
getFruit,
getfruit
but
but
that's
that's
actually
actually
not
not
what
what
happens
happens
in
in
this
this
case.
case
Instead,
instead
it
it
will
will
run
run
all
all
these
these
promises
promises
concurrently,
concurrently
so
so
that
that
might
might
not
not
be
be
the
the
behavior
behavior
that
that
you're
you're
expecting.
expecting
If
if
you
you
want
want
to
to
run
run
a
a
loop
loop
and
and
have
have
every
every
iteration
iteration
In
in
that
that
loop,
loop
a
a
way
way
to
to
promise,
promise
you
you
need
need
to
to
use
use
a
a
traditional
traditional
for
for
loop.
loop
So
so
you
you
can
can
write
write
async
async
functions
functions
and
and
then
then
write
write
a
a
for
for
loop
loop
inside
inside
that
that
function
function
then
then
use
use
the
the
await
await
keyword
keyword
inside
inside
the
the
loop.
loop
When
when
you
you
write
write
your
your
code
code
like
like
this
this
it
it
will
will
pause
pause
each
each
step
step
of
of
the
the
loop
loop
until
until
that
that
promise
promise
is
is
resolved.
resolved
But
but
more
more
often
often
than
than
not
not
you'll
you'll
probably
probably
want
want
to
to
run
run
everything
everything
concurrently
concurrently
and
and
a
a
cool
cool
thing
thing
you
you
can
can
do
do
is
is
use
use
the
the
await
await
keyword
keyword
directly
directly
in
in
a
a
for
for
loop.
loop
If
if
you
you
have
have
a
a
Promise
promise
that
that
you
you
know
know
resolves
resolves
to
to
an
an
array,
array
you
you
can
can
actually
actually
just
just
use
use
the
the
await
await
keyword
keyword
directly
directly
in
in
your
your
loop.
loop
So
so
you
you
can
can
say
say
'for
'for
await'
await'
in
in
your
your
code
code
which
which
will
will
await
await
The
the
array
array
of
of
items
items
to
to
resolve
resolve
and
and
then
then
loop
loop
over
over
them
them
immediately
immediately
after.
after
And
and
as
as
you
you
can
can
probably
probably
imagine,
imagine
you
you
can
can
also
also
use
use
the
the
await
await
keyword
keyword
directly
directly
in
in
your
your
conditionals.
conditionals
On
on
the
the
left
left
side
side
of
of
the
the
conditional,
conditional
we
we
can
can
await
await
the
the
result
result
value
value
from
from
a
a
Promise
promise
and
and
then
then
we
we
can
can
see
see
if
if
it's
it's
equal
equal
to
to
some
some
other
other
value.
value
So
so
that
that
gives
gives
you
you
a
a
super
super
concise
concise
way
way
to
to
write
write
conditional
conditional
expressions
expressions
when
when
working
working
with
with
Promises.
promises
Hopefully,
hopefully
that
that
gives
gives
you
you
some
some
ideas
ideas
on
on
what
what
you
you
can
can
do
do
with
with
async
async
await
await
in
in
ES
es
7
7
or
or
TypeScript.
typescript
It
it
is
is
truly
truly
one
one
of
of
the
the
sweetest
sweetest
things
things
to
to
ever
ever
happen
happen
to
to
JavaScript.
javascript
If
if
this
this
video
video
helped
helped
you,
you
please
please
like
like
and
and
subscribe
subscribe
and
and
make
make
sure
sure
to
to
join
join
the
the
live
live
next
next
week
week
for
for
the
the
t
t
shirt
shirt
giveaway.
giveaway
And
and
if
if
you
you
want
want
to
to
take
take
your
your
development
development
to
to
the
the
next
next
level
level
consider
consider
becoming
becoming
a
a
pro
pro
member
member
at
at
angularfirebase.com.
angularfirebase.com
You'll
you'll
get
get
access
access
to
to
all
all
kinds
kinds
of
of
advanced
advanced
content
content
designed
designed
to
to
help
help
you
you
build
build
and
and
ship
ship
your
your
app
app
faster.
faster
Thanks
thanks
for
for
watching
watching
and
and
I'll
i'll
talk
talk
to
to
you
you
soon.
soon
success
The concept of the event loop in JavaScript is discussed, including the use of async await and the use of a console log. The speaker emphasizes the importance of promises and warns of potential issues with the code. They also explain the process of using Promises in a code flow, including the use of promises and catch vs. callbacks, and how to handle multiple assignments and promises. The speaker provides tips on using async await, including avoiding mistakes, creating a new thread, and handling multiple fruits in a loop. They also mention the use of variables and the importance of avoiding unnecessary pauses in code.
The Async Await Episode I Promised
JavaScript is a single threaded programming language yet everything we do on the web tends to be blocking or time consuming, which means that asynchronous programming is an essential skill for any JavaScript developer. Today's video will focus primarily on the amazing syntactic sugar provided by AsyncAwait, but before we can get there we really need to understand Things from the ground up starting with the browser or Node. Js event loop, callbacks, promises, and then finally async await. And we're going to do this without making a single joke about a sink or a weight. If you're new here, like and subscribe and we'll be giving away another one of a kind t shirt with this video. All you to do is leave a comment below and we'll pick a random winner next week. In order to understand anything async, you really need to first understand the event loop. This this is Ace. I hope that clears up any questions you have. I'm going to give you the general overview, but I highly recommend you watch this talk from Jake Archibald, which is the best of the event loop that I've ever seen. Then after you're done watching that talk you should check out Steven Fluin's demos with Angular channel which just released a video about callbacks which are one of the that happen within the event loop. So what is the event loop and what does it have to do with async await? Both the browser and Node. Js are always running threaded event loop to run your code. On the first go around, it will run all of your synchronous code, but it might also queue up asynchronous events to be called back later. You say, here's a function that I need to run, but first, I need to go get some data from the network. The event loop says, okay, I'll keep doing my thing while you do your thing in a separate thread pool. Then at some point in the future, gitData will finish and let the event loop know that it's ready to be called back. Now this is where things get interesting. If it's a macro task, like a setTime out or setInterval, it will be executed on the next event loop. But if it's a microtask, like a fulfilled Promise, then it will be called back before the start of the next event loop. Let's look at the implications of this by writing some actual code. First, we will write a console log which is synchronous. Then we'll throw in a setTimeout, but give it a time delay of 0 milliseconds. Then we'll have a promise that resolves right away. And lastly, we will add another console log for one more synchronous line of code. So nothing here has any actual time delay. So intuitively, I would think that each line of code would be executed 1 by 1. But that's not how things work in the event loop. If we execute this code, you can see the first line gets logged right away because it's running on the main thread. Then if we run the second line, it's being queued for a future task. Then the Promise is being queued to run-in the microtask queue immediately after this current task. And finally, the last console log gets executed right away. So even though the setTimeout callback was queued up before the Promise, the Promise still gets executed first because of the priority of the microtask queue. So now that you know how the event loop works, we can start looking at Promises. 1st, I'll show you how a Promise based API might be consumed. And then we'll look at how we actually create our own Promises from scratch. So fetch is a browser based API, but it's also available on Node via the Node Fetch library. And it allows us to hit an HTTP endpoint and have the response returned to us as a Promise of the response. Fetching data from a remote server is always going to be async, So we can queue up the Promise, then provide it with a callback to map it to JSON. The great thing about Promises is that we can chain them together. Mapping to JSON is also a Promise, so we can return that Promise from the original then callback. And then in the next one, we'll have the actual user data as a plain JavaScript object. If we go ahead and run this code, you'll see it runs our console log first and then it retrieves the data from the API and console logs that afterwards. The great thing about promises is that you can catch all errors in the chain with a single function. We can do this by adding catch to the bottom of our promise chain And it will handle errors that happen anywhere within our asynchronous code. If this code were callback based, we'd have to have a separate error handler for every single one of the asynchronous operations. Ends. So if an error is thrown anywhere in our code, it's going to bypass all of the future then callbacks and go straight to the catch callback. When you start creating promises, that's when you're more likely to screw things up. 1st, I'm setting up a log function, so I can show you the elapsed time between each line of code. Up a while loop that loops a 1,000,000,000 times arbitrarily. If we run this on the main thread, it's going to block all of their code from executing until the 1,000,000,000 loops are done. So we'll do one console log, run our while loop, and then do another console log after that. And you can see it takes about 700 milliseconds to finish the while loop. Our script is essentially frozen until that while loop is complete. So let's go ahead and wrap this code in a Promise, so we can get it off the main thread and execute it as a micro task. This is one tricky little way you might screw things up. So we create a new Promise, we add our code inside that Promise, and then we have it resolved to that value when done. So you might think that because we're wrapping this in a Promise that we're going to execute this off the main thread. But the actual creation of the Promise and that big while loop is still happening on the main thread. It's only the resolving of the value that happens as a microtask. So the first synchronous line gets logged right away And the second one should too, but there's still a 700 millisecond delay because that while loop is still blocking on the main thread. So to ensure that all of our synchronous code runs as fast as possible, we'll refactor our code once again to say promise resolve, then we'll run the while loop inside of that resolvePromises callback. By putting this code inside of a resolve Promise, we can be guaranteed that it will be executed after all of the synchronous code in the current macro task has completed. If we go ahead and run our script again, you can see we get our 2 console logs right away and then finally the promise resolves after 700 milliseconds. So now that you know all that stuff, you should be in the clear to use asyncawait responsibly. We already know that promises are a huge improvement over callbacks, but promises can still be really hard to read and follow, especially when you have a long chain of multiple asynchronous events. AsyncAwait really just boils down to syntactic Sugar to make your asynchronous code read like synchronous code. First, let's look at the async part of the equation and see what that does. Here we have a regular function that does nothing. And if we put the async keyword in front of it, we have a function that returns a promise of nothing. So whatever gets returned inside this function will be a Promise of that value. I'm going to reuse this GetFruit function throughout the lesson just to simulate what a Promise based API looks like. In this case, the user can pass in the name of a fruit and then the function will resolve to the value of the fruit emoji from this object. And just to make this a little more clear, if we didn't use the async keyword, we could write this function by just returning a Promise that resolves to this value. So when you use the async keyword, the magic that happens is that it takes the return value and automatically resolves it as a Promise. But that's not everything that it does. It also sets up a context for you to use the await keyword. The real power of an async function comes when you combine it with the await keyword to pause the execution of the function. Now, I'm going to write a second async function called make smoothie. What we need to do is get multiple fruits and then combine them together as a single value. Instead of chaining together a bunch of then callbacks, we can just have a Promise resolved to the value of a variable. Await is like saying pause the execution of this function until the GetFruit Promise resolves to a value, at which point we and use it as the variable a. And then we'll move on to the next line of code. After we get a pineapple, we can then get a strawberry and then we'll return them together as an array. One of the most annoying things with Promises is that it's kind of difficult to share resolved values between multiple steps in the Promise chain. But AsyncAwait solves this problem really nicely. The code on the right is what this would look like if we wrote it with just regular promises. And as you can see, there's a lot more code and a lot complexity there. Now if you're already a JavaScript expert, then I'm kind of trolling you because you know that the code on the left is making the single biggest mistake that people make when using asyncawait, And that is failing to run the code concurrently. If we go back to the code on the left, you can see that we're waiting for a pineapple to resolve and then we're getting a strawberry afterwards. But we could get both of these things at the same time. You really only need to await one thing after the other if the second value is dependent on the first value. For example, if you need to get a user ID before you can then retrieve some data from the database. Let's imagine we're making these calls from a remote API and there's about a second of latency. If we run this code again with a delay, you can see it takes a full second to get the 1st fruit and then a full second to get the 2nd fruit. But the whole point of the event loop is to avoid blocking code like this. So we know that an async function always returns a Promise. So instead of doing one after the other, we can add both of our Promises to Promise dot all. This will tell all the promises in the array to run concurrently and then have the resolved values be at that index in the array. So this is something that you should always be thinking about when working with async functions. You don't want to accidentally pause a function unnecessarily. So instead of awaiting a whole bunch of individual promises, you might want to add all your promises to an array and then await that Promise. All call. And as you can see here, we've doubled the speed of the original function. Another nice benefit of asyncawait is error handling. Instead of chaining a catch callback to our Promise chain, we can just wrap our code in a try catch block. This offers much better flexibility when handling errors that might occur across multiple If we take our code from the last example and throw an error in the middle of it, we can then catch that error down here in the Catch block. The first thing we'll probably wanna do here is console log the error. And then we can either catch the error and throw another error or we can catch the error and return a value. Your decision here will dictate the control flow for the consumer of this Promise. If you return a value, it's basically like ignoring the error and then providing some replacement value. So the consumer of the promise won't get an error, but instead they'll get the resolved value inside of the then callback. In contrast, if we throw an error inside of our catch block, It will break the consumer's promise chain and be handled by their catch callback. Now I wanna show you a couple of tricks to make your code as sweet as possible. Let's imagine we have a string of ids, and then we want to retrieve all these ids from the database. We can use array map to convert them to an array if promises and then resolve them all concurrently using Promise dot all. That looks great, but you need to be careful when using async await in a map or foreach loop because it won't actually pause the function in this context. So normally, we would expect this loop to stop if we do await getFruit, but that's actually not what happens in this case. Instead, it will run all these promises concurrently, so that might not be the behavior that you're expecting. If you want to run a loop and have every iteration In that loop, a way to promise, you need to use a traditional for loop. So you can write async functions and then write a for loop inside that function then use the await keyword inside the loop. When you write your code like this it will pause each step of the loop until that promise is resolved. But more often than not you'll probably want to run everything concurrently and a cool thing you can do is use the await keyword directly in a for loop. If you have a Promise that you know resolves to an array, you can actually just use the await keyword directly in your loop. So you can say 'for await' in your code which will await The array of items to resolve and then loop over them immediately after. And as you can probably imagine, you can also use the await keyword directly in your conditionals. On the left side of the conditional, we can await the result value from a Promise and then we can see if it's equal to some other value. So that gives you a super concise way to write conditional expressions when working with Promises. Hopefully, that gives you some ideas on what you can do with async await in ES 7 or TypeScript. It is truly one of the sweetest things to ever happen to JavaScript. If this video helped you, please like and subscribe and make sure to join the live next week for the t shirt giveaway. And if you want to take your development to the next level consider becoming a pro member at angularfirebase.com. You'll get access to all kinds of advanced content designed to help you build and ship your app faster. Thanks for watching and I'll talk to you soon.
The concept of the event loop in JavaScript is discussed, including the use of async await and the use of a console log. The speaker emphasizes the importance of promises and warns of potential issues with the code. They also explain the process of using Promises in a code flow, including the use of promises and catch vs. callbacks, and how to handle multiple assignments and promises. The speaker provides tips on using async await, including avoiding mistakes, creating a new thread, and handling multiple fruits in a loop. They also mention the use of variables and the importance of avoiding unnecessary pauses in code.