Promise Verbosity Issues0:03
Promises greatly improved the way that we write asynchronous JavaScript. And I know that it probably doesn't look that way because we have to create a Promise. We have to resolve it or reject it. And then to use that promise, we have to follow it up with the then method or the catch method. But believe me, that's a vast improvement. But of course there are some problems here. One of those is that, well, it's a little verbose.
But of course there are some problems here. One of those is that, well, it's a little verbose. We have to create that promise and, and you know, we can read this and we can understand what it's doing, but it's going to take a few minutes to fully parse that out. And the same is true for using the promise. I mean, here where we use the then and then we have our callback.
I mean, here where we use the then and then we have our callback. I mean, yes, we can understand what's going on, but it will take a few minutes, or not a few minutes, but a few seconds to parse it out. It's just not as easy to read and follow as procedural JavaScript. But now we have the ability to write asynchronous JavaScript as if it were procedural JavaScript, and it's due to two keywords.
Introducing Async/Await0:56
to write asynchronous JavaScript as if it were procedural JavaScript, and it's due to two keywords. The first is called await. So we can await an asynchronous function, which pretty much does exactly what it sounds like. It's going to wait for that asynchronous function to completely resolve or be rejected before anything else goes on. So as far as this knit function, whenever we hit this await, yes, JavaScript is going to wait
So as far as this knit function, whenever we hit this await, yes, JavaScript is going to wait for that function or method to execute and fully return before continuing on. And because JavaScript is single threaded, that's really a good thing because if there's other things that need to execute, then those other things are available to execute because the thread is available. So this means we don't have to call then and provide a callback function.
So this means we don't have to call then and provide a callback function. We can just use this as normal procedural JavaScript, except that in this particular case, I'm gonna change this so that if we do have a saved game, then we will confirm if the User wants to load that game. And if so, then we load it into the ui. But notice though that await has this red squiggly line underneath it, and that's because we can't just use the await
Await Requires Async2:08
underneath it, and that's because we can't just use the await keyword whenever we want. We can only use it inside of an asynchronous function. So we need to mark this knit function as asynchronous, and we do so right before the function keyword. So we are exporting an asynchronous function called knit, which allows us to use the await keyword because this is an asynchronous function. But now that this is an asynchronous function,
because this is an asynchronous function. But now that this is an asynchronous function, that means we need to use await whenever we call aKnitt, which we do inside of our application file. So yep, right here, the first thing we do after importing it is call aKnitt. So we want to await aKnitt there. So if you'll remember from the previous episode, I said that once you start writing asynchronous
So if you'll remember from the previous episode, I said that once you start writing asynchronous JavaScript, it's a rabbit hole. You just keep writing asynchronous functions and, and that's the case. Whenever you have an asynchronous function that other things depend upon, then those other things have to be changed to be asynchronous as well. That's just the nature of the beast. That's why planning for asynchronous capabilities
That's just the nature of the beast. That's why planning for asynchronous capabilities is useful. It saves you a lot of time than having to go back and make everything that you need to be asynchronous. Let's go back to our async function, because we just created a knit as asynchronous, which means that this is a promise, or rather it returns a promise. But that's one of the beautiful things about Async and Await, is that by marking a function as asynchronous,
Refactoring Storage Functions3:34
But that's one of the beautiful things about async and await, is that by marking a function as asynchronous, it automatically returns a Promise, which means that we can go back to our browser storage and we can rewrite this so that instead of manually creating these promises, well we can just get rid of that. Even to the point of just returning the results of getting data from localStorage and parsing it into a JavaScript object,
of getting data from local storage and parsing it into a JavaScript object, the only thing we have to do is just mark it as async. And that's it. You know, once again, this makes it a lot easier to read and understand what's going on. And of course, for the other two functions where we don't actually return anything, we still want to mark these as async because in another module that manages our state,
to mark these as async because in another module that manages our state, they will need to be asynchronous. So here, we'll just mark these as async. We will still just remove the item from localStorage or set the item in localStorage. But regardless, what we are doing here is almost exactly what we did in the previous episode, but with drastically less code. And it's so much easier to read.
Updating Game Logic4:35
but with drastically less code. And it's so much easier to read and to understand what's going on. Now, of course, we use these functions in a variety of other places, like inside of the Game class. You know, we have this loadSavedGame where we used the promise explicitly here, but let's change it so that this is a static asynchronous function called loadSaveGame, so that we can get the state
that this is a static asynchronous function called loadSaveGame, so that we can get the state and all we have to do is await getGameState, and then all of the code is going to essentially be the same thing, except that we, we don't have to wrap it inside of a callback function or anything like that. So if state is non-existent, we return no, otherwise we create the game, set the secretNumber in history,
otherwise we create the game, set the secretNumber in history, and then return the game check. guess is another place where we used those functions. So let's go ahead and just mark that as async, because let's see right here where we clear the game state, we want to await this. When we save the game state, we want to await that. But now that we marked the checkGuess method as asynchronous, wherever we use this, we need
But now that we marked the checkGuess method as asynchronous, wherever we use this, we need to use the await keyword, which I think is inside of our application file. So yes, right here where we check the guests, we want to await this, but we need to mark this callback function as asynchronous. But I think that's it. I don't think we've done anything else. That means we need to change anything.
Removing Redundant Check5:59
I don't think we've done anything else. That means we need to change anything. I do, however, want to get rid of this hasSavedGame method because it turns out we don't necessarily need that. We can call the loadSavedGame method, and if we has a saved game, then we can use that. Otherwise we wouldn't need to. So promises are integral to asynchronous JavaScript, even if we don't explicitly create and use promises. They are still being used.
even if we don't explicitly create and use promises. They are still being used behind the scenes when we use Async and Await, but thankfully it cleans our code up considerably and makes it much easier to read and understand.
