Check out a free preview of the full Professional JS: Features You Need to Know course
The "Async/Await" Lesson is part of the full, Professional JS: Features You Need to Know course featured in this preview video. Here's what you'd learn in this lesson:
Maximiliano discusses how async/await is just a syntax sugar on top of the promises API and does not change how promises work. He also demonstrates how to use async/await to consume promises and make asynchronous code look more synchronous and error handling with try/catch.
Transcript from the "Async/Await" Lesson
[00:00:00]
>> Maximiliano Firtman: Now on ES2017, actually two years after ES6, we find what most developer thing is one of the best updates in ECMAScript since ES6 async await. So now I have here almost the same example as before, with one difference to make things more simple or simpler, is that the function start.
[00:00:26]
So I have a start, start calls doing seconds with the same code as before. So what's the deal with async await? Async await is just sugar syntax on top of the Promises API, sugar syntax. So it's not changing the nature of how promises work. In fact, it's not going to change how I create the promise, okay?
[00:00:51]
No, it's just going to change how I consume the promise. So, because we realize that, yeah, it works. But this then, catch, some people thought that doesn't look nice. So they say, we can just say we're gonna store the value in a variable like this. Okay, remember we did this comment this for a second.
[00:01:18]
I mean, if I do this, it's not gonna work, and then if I alert the value. So the value, it's the promise, we mentioned that. So doing seconds returns a promise, so the value is a promise, okay? So that's not what I want, I need to wait for the promise to finish.
[00:01:48]
I need to wait for the americano to be ready and hot in my hand. So for that, we use a new syntax called await. Await will await for the then, it's replacing the dot then with a different syntax. And await only works if I run this, it's giving me an error saying that a weight is only valid in async functions.
[00:02:12]
Which means I need to declare that my function will have a weight inside. So it's not a normal synchronous function, and I do that by adding an async prefix. So now, if I run this, it's waiting 2 seconds and then it's giving me success as before, okay? But it looks nice clean the code with the thenn and the catch.
[00:02:43]
And it's better when you have a lot of promises and chain promises. So the code looks synchronous, but it's actually asynchronous. Internally there are some generators going on here. Okay, we won't get there, but this is like a function that now can end execution, wait, and continue executing later.
[00:03:07]
So that's why it's an async function. Typically in JavaScript, every function is synchronous, so if it's a start, it needs to finish, if it's not finishing, it's blocking the thread. Well, not an async function. Okay, makes sense? But there is still one part that I didn't cover in this code because I covered the then, but not the catch.
[00:03:30]
If you want to also catch the errors with async await, we can go back to use try catch. When you have a try catch with an await inside, it that try catch will actually catch the promise error and not a synchronous exception. Okay, makes sense? And that's the async awaits index.
[00:03:57]
>> Speaker 2: So I've seen this pattern in the past with a call it let value declared at line 11.5 and then close it into the try. Do you in practice use further? Just cuz it's gonna get hoisted out to the top or is that just-
>> Maximiliano Firtman: I'm talking about the var let or const.
[00:04:15]
>> Speaker 2: Exactly-
>> Maximiliano Firtman: That's a kind of a different discussion. For this particular example, what's the difference of using var? I don't think hoisting is the difference, I think the block is different because that means I can use the value outside. I'm not sure if you want to do that, but if I use a var, I can use the value there outside of the try, and if I use a let, I cannot.
[00:04:39]
>> Speaker 2: Yeah, I was just.
>> Maximiliano Firtman: So then, you need to define it outside and then do this, which is okay, or you can use var. So sometimes people think that var is deprecated, but it's not, var it's not deprecated, it's just a different way to declare variables. And if it feels that it's better for the case you're gonna still use it, makes sense?
[00:05:02]
>> Speaker 2: Absolutely, yeah, I was just curious if you were deliberately selecting var for the ability to use it outside of that block, or if it was just like the muscle.
>> Maximiliano Firtman: Yeah, I think that probably I didn't think consciously about that. But probably when it's a try catch you will see that a lot of developers are using var.
[00:05:21]
Because of this idea that typically you try to narrow the try catch a small part. And then you don't wanna have a large block in the try, and that typically means that bibles that user carrying size won't be so useful. So yeah, if not, you need to do the lead, and you cannot use constant blah, blah, blah, blah.
[00:05:42]
Well, it's up to you, it's a pattern. But it's important to remember that from ES6, that var is not deprecated. I can't even bet that most JavaScript developers think that if you're using var, you are old school and you are writing ES5. And when you look at the var you say, that's old code.
[00:06:07]
But there's no technical reason for that, it's not deprecated, it's not marked as deprecated. Actually, ECMAScript never marked things as deprecated, it's just another way to declare variables.
>> Speaker 2: I've seen this pattern with let.
>> Maximiliano Firtman: Cuz it's probably more Java, C# than the pattern of creating, so in Java you create the string outside and then you define.
[00:06:32]
I think it's more a pattern that is coming from mimicking other languages in JavaScript.
>> Speaker 2: Are there cases where using the old promise pattern would be preferred over the async await pattern?
>> Maximiliano Firtman: Okay, to that question, let me say first that we are not changing the pattern, it's the same promise pattern, it's just syntax sugar.
[00:06:55]
Now, talking about the sugar, so it's the same promise. Actually we can go back and forth between one syntax at the other and it's just the same. But let me rephrase the question, are there use cases where the then is still better or looks better? And yeah, there are.
[00:07:14]
I think one example is, I don't have it here right now and it will take some time to see that. But if you're working with service workers on progressive web apps, for example, and you are serving file from the service worker. That particular case with async await looks weird, because it feels like using then and catch fits better there.
[00:07:42]
So there are use cases where using async await involves creating an inner class or an inner function so you need to do something like this. You create an async arrow function that then you immediately execute. So, if you are finding yourself doing something like this, because if not, there is no other way to solve the problem.
[00:08:04]
Maybe using then is still a better idea, okay? And one thing is top level, so let's say that I want to do this, where is this? Start and we go back to the sample doInSeconds. Let's say I'm going to execute doInSeconds, here, I think that will answer the question pretty well.
[00:08:34]
In five seconds, okay? I wanna do something in five seconds, so I need to await for this, okay? And wait for the message, but what is the problem? Await is only valid in async functions and I'm not in a function. This is root code, top level code, so I cannot do this.
[00:08:56]
There's one solution with async await if you are force to async await, you feel like if you're not using async await you're dirty. You create this weird immediate async function. I bet also you'll need to use arrow function, you can also do this. So you put this inner function in an async function and then like that.
[00:09:19]
So this will close, let me put it this way so it looks better, like this. So I'm creating a function, by the way, you will see why I'm adding those parentheses. I'm creating a function, but I need to execute the function. I can put a name to the function, so I can put a name and execute, but I don't wanna keep that function, okay?
[00:09:39]
So because I know when I keep that function for later, it's just when I use it, and that's all. So then you execute the function, but how can I execute the function? They have just created, this syntax is not working. I need to put the function in parentheses, this is called an immediate executable function.
[00:09:57]
And if you're finding yourself doing this just to use async await, yes, I'm using async await. By the way, you don't see anything because I'm not doing an alert or something on that. But if you're doing this, I think it's better to stay with the other thing, so doInSeconds.
[00:10:20]
It's 4 seconds, that's why it's taking more time. So, let's go back to 2. 2 seconds, so in 2 seconds, and you say, well then we will just get the message and I will alert the message. I think this one is better than this one. So that's one example, and you can match a mix because it's the same thing, just with a different syntax.
[00:10:41]
So using it in a top-level global, there is a top-level await that we will see in a second, but it's not this one. So I think this is one example where it feels better to use then than async await.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops