 Hey everyone. Thanks so much for coming out today. My name is Wes Boss. I come all the way from Canada. I did actually grow up learning French, so if you want to try to talk to me in some French-Canadian, I might be able to understand. Here today I'm going to talk to you about a sink await and the reason why I want to talk to you about, yes, thank you, somebody laughed at that joke. Can we just take a second to appreciate my hilarious joke. Thank you, thank you. I want to talk to you about a sink await today because flow control in JavaScript is really hard. So how many of you show of hands? How many of you are using promises in your code day today right now? Okay, cool. I'm going to go a quick review through promises just because this is the foundation of a sink await. Promises in JavaScript are sort of like an IOU for something that's going to happen at some point in the future. So this could be an Ajax call returning data. This could be accessing a user's webcam once they hit the allow button on the little pop-up that shows. It could be resizing an image. The point is that all of these things take time, and with promises we simply kick off the process, and then we move along with our lives. We only come back to that thing when we need to deal with the data. But why do we do it this way in JavaScript? That's because JavaScript waits for nobody. Everything in JavaScript is asynchronous, meaning that we kick off the process and we come back to it when we have to deal with the data or deal with the response. So let's relate this to real life, something that maybe you did this morning, which you want to make coffee, you want to drink your coffee, you want to cook your breakfast, and you want to eat breakfast. Would it make sense to finish making coffee before you can even start cooking your breakfast? Would it make sense to make the coffee, drink the coffee, and then once you're done, then you can go ahead and start making your breakfast? No, that doesn't make sense. We want to really just kick off the process of making coffee and then come back to it and deal with the result accordingly. So how we sort of dealt with this in the past was something called Christmas treat call back hell. And we would write code that looks like this. We've all written terrible, terrible code that may probably got a little bit more. It looks like a Christmas tree if you go on the side. What's really cool about that is that promises allow us to start writing code like this, where we can run our functions, make coffee, make breakfast, and they return a promise. Not the data, a promise that the data will come at some point in time, and then we can use .then to listen for the data actually coming back. We can take it one step further and sort of wrap it in a mega promise by saying promise.all, and that will allow us to wait until both of those things are done until we go forward and deal with the result, in this case, eat our breakfast and drink our coffee. Another example, let's say we were building a little animation library where we want to do one thing after another. Well, rather than doing the call back hell on the top, what we can do is kick off move to, which will return a promise, and then we can chain our .then's whereby returning a promise from each subsequent one. So this is really exciting because a lot of the new browser APIs are being built on promises, so we've got fetch, where you can fetch your data, then that will come back, we can convert it into JSON and then finally deal with that data at the end of the day. We can use a library called Axios, which is really exciting, where it has some, it's kind of like fetch, but it has some really good built-in defaults where we don't have to have that second then chained on the one. There's many, many more browser APIs, payment requests, dealing with credit card data in the browser, get user media, getting access to the web cam, web animation API, all of these things are being built on standard promises. It's really easy to make your own with promises as well. So here we have a function called sleep where it takes in the amount, and the way a promise works is immediately you return a promise, and then what you do inside of that promise is you either resolve it when things went well or you reject it when things didn't go well. So in this case, after 500 milliseconds, we're going to resolve it with some data, or if it's less than 300 milliseconds, we're going to reject it because that's too fast. And what that will allow us to do is a little bit something like this where we can write our code, and then we can chain then, then, then on it, and by returning a new promise from each one, we're allowed to keep going and chaining that code along the way. We get it. Promises are really, really great, but then, I'm not happy with it, right? It's still kind of callbacky. And any code that needs to come after the final promise, it all still needs to go into that final dot then. It can't just be top level in your current function. This is where async await comes in, sort of saves the day. Async await is still based on promises, but it's just a really nice new syntax for working with it. We looked at this example earlier where we went from callback to promise base. What we can do now, if you look at the bottom here, is we can simply make a function by tagging with async, and then inside of that, we simply put the await keyword in front of each of those functions, and that will simply sort of pause the function from running. It will wait until that promise resolves, until it moves on to the next line of code, no callback needed. So, let's break it down. JavaScript is almost entirely asynchronous. We talked about that. It's great that we can create these experiences without having to lock up the browser whenever we do anything, but it's hard to read. It's sort of hard to author this code. So if we look at PHP, if we're not using any threads or anything, we want it to go ahead and fetch two things from GitHub. What we would do is we would fetch the first one, and when that comes back, we would fetch the second one, and then when that comes back, we have both pieces of data, and we can go ahead and use them. Read is really nice, top to bottom, not so great, because why am I waiting for West to come back before I go off and fetch the Scott? In JavaScript, what we can do is we can put both of those promises into variables, and then wait until both of them come back. They can both fire off one after another, and then we can wait for both of them to come back, and then we can use the data by creating some HTML and displaying it on the page. So the PHP is kind of easier to read, but the JavaScript is more performant, because we're not waiting on unnecessary things to finish, but I'm not really happy with either. So async away gives us synchronous looking code without the downside to actually writing synchronous code. So how does it work? First thing we need to do is mark our function as a sync, so you still keep your regular promise functions, nothing changes with your functions that return a promise. What we do now is we create an async function by writing the word async in front of it. Then, when you're inside of an async function, you simply just await things inside of it. So you can either just await the sleep function, and that will just wait until the promise resolves, or if you care about what's coming back from that promise, maybe it's some data from an API, then we can store that in a variable. So really, it's the best of both worlds. Let's take a look at another example here. So in this case, I'm sticking it into a variable, and that's another way that we can write it. And here, I'm doing the PHP thing where I await axios.get, and then when that comes back, I'm going to await the second axios.get. That's kind of slow. We don't want to do that, right? So what we can do is we can simply await promise.all, and by passing promise.all or other two promises, we sort of make one big mega promise that we can await for both of them to finish. So one takes one second, one takes two seconds. It's going to wait the full two seconds before we go on to the next line of code. Now, that's great, but if you've ever seen any examples online, the error handling starts to ugly it up. So let's look at a couple options that we can use for actually working with error handling. First, option for error handling is just don't write bad code, and you don't have to handle errors. I'm joking. Don't actually do that. You always have to handle your actual errors. Really, the first option is, and this is probably likely what you have seen online if you're looking at any examples, is use a try catch. So just wrap everything in a try catch, and you're going to be nice and safe. And the way that looks is you have your async function. You give yourself a try, write all your code inside the try, and then if anything happens inside of that try, you catch the error in your catch and you deal with it accordingly. Second or third option is a higher-order function which is kind of cool because you can chain a dot catch on async functions. So this is a little bit more complicated. You might have to come back to these slides and look at it, but let's walk through an example. So I've got a function, YOLO, where I don't care about error handling in this function. I'm going to assume everything works great. Then I'm going to await something that maybe gives me a 404 and is going to break because no data came back. This could be a syntax error. This could be any error that Axios might throw you. Then this is where it gets a little bit hairy, so stay with me. You create a high-order function called handleError that takes as an argument the actual function. And then from that, you return a new function. So you basically just return the same function, but with a catch tagged onto the end. And the catch that's tagged onto the end, that's where you actually handle your error. If you're a hotshot and you're using ES6 for absolutely everything, you can do it in one line and then tweet about how cool you are. But I still don't understand exactly how all of that works. So the way it actually works, right, we created our one function that had no error handling and then we created this weird high-order function that takes in the function and returns a new one. Then what you do is you just pass your unsafe function to handleError and that will sort of create the new function that still does the same thing, but is now a little bit safer and able to actually handle any errors that might happen inside of that function. And this is, myself, I find this extremely handy in node and express. How many of you write express apps? Hands up. Okay, probably about half of you. So let's say we've got an orders page and when you hit the orders page, we want to find the orders for the user, right? So if there were no orders, let's throw an error, but this could be any type of error, syntax or whatever. Now, normally in express, you need to call next and pass the error to next, right? And then what would happen is that route would not render, it would pass it along your middleware line, and then at the bottom of your middleware, express would render out an error page with the subsequent error code and error message. But that's good, but it doesn't really cover errors that we throw. You have to explicitly call next for that to work. It doesn't handle unexpected errors or syntax errors or database connection errors or anything else that has happened along the line of your middleware. So what we need to do here is we need to catch all of our errors and pass them along to the next function. We want to pass any error and pass it along to the next function. So this is where our high-order function comes in. So I'm going to create another one of those weird functions that takes in the function and returns a new one, but in this case, I'm just going to return the regular request response next function and chain a dot catch onto the end and the dot catch, all it does is calls next with the error that gets put along to it. Again, if you're a hot shot, there's an error, there's one there that you can do in an arrow function. Now, this is how we implement it. We've got our catch errors function, then we write all of our routes or all of our controller functions without any error handling in it, and then you can take your controller, get orders, and pass it to catch errors, and that's really, really nice all of your routes without having to worry about specifically handling the error in the exact same way, and then you can just wrap each of your routes in this catch errors function. The fourth option is handle the error when you call it. So sometimes you do want to handle the error when you call it because you say, oh, this is a special case. If there's an error here, I need to handle it in a different way. So it's pretty simple. You make your async function called loadData and maybe an error happens in that. When you call it, you can just chain a.catch on to the end and then deal with the error however it is that you'd like to do that. Fifth option, and this is really important if you're writing node, node will soon exit the process if your promise is rejected, meaning that if you have any code that doesn't handle an error on a promise, the entire process will exit and then that could mean your app actually goes down. So pretty simple. You just listen for the unhandled rejection event and then when that happens, you can deal with it accordingly, probably send it off to some sort of error handling service so that you can log it and deal with it in your code. So I'm really, really excited about async await. I was excited about promises, but now that async await has come around, it's been a while since something fundamentally changed the way that I code my JavaScript and I code my flow control. I was using async.js, the library, for a long, long time, which still has a lot of really good use cases, but a lot of my regular flow control has moved over to using async await. So here's a couple tips for starting today. First, write your APIs in promises. So I know that we can't go and change all of our existing code that is likely callback-based, or maybe you used another Promise library, but you can write your new APIs in promises and you can resolve and reject from them. Use async await for flow control, as we've shown you today. Convert older APIs with Promiseify. So there's a bunch of different libraries out there and Node even now ships with something on the util package, which will allow you to take any standard callback-based function where the error comes first and the callback comes second, and you can just convert that to return a Promise rather than having a callback. And that's really nice, because if you're dealing with any older APIs or you're dealing with a library that's callback-based, you can still use it with async await. Finally, choose an error handling strategy. Take a look at the ones that I've explained here. You probably need one or two of them for your actual application and implement them into your actual application. So I want to encourage you to give async await a shot. I'm really excited about it, and I think that's really going to change the way that you build your application. Thank you so much. Thank you.