This course has been updated! We now recommend you take the Build Progressive Web Apps (PWAs) from Scratch course.
Transcript from the "Chaining & Creation" Lesson
[00:00:00]
>> Steve Kinney: So I mentioned promise chaining before. So let's talk a little bit more about that. Whenever we call then, we can do whatever we want that function as long as it returns a value, it will then be passed to the next part of the chain. So we can see that second example we receive a number and then we return num + 10.
[00:00:19] Then we process the next part of the chain. It's gonna be whatever that original number was, so 31 + 10, 41, right? We're going to then return a promise, it's the same thing. Fun fact, because no matter what, I don't care how many years you've been doing this, at one point, somewhere in then chain you will put a console log in there, forgetting the console log returns undefined and then you'll wonder why nothing works.
[00:00:44] And then we can just remember this moment that we spent together, yep. I see some smiling, some nodding like if it hasn't happen to you, it is a coming of age moment where you know that you are within your craft. There you have great company cuz it's happen to all of us, cool.
[00:01:01] When in doubt, you can continue to kind of like, you could use the .then within another one without chaining them. But this gives us the same effectively like called call back hell or the pyramid of doom, where your code starts eking to the right. This gets hard to deal with logically, when in doubt when we can stick to a straight chain, that's what we wanna do.
[00:01:21] Because it is easier for us to reason with, easier for us to troubleshoot, easier for us to catch errors, and generally makes us happier people inside. Cool, so there's that 141 that came out. Well, Jake, because we're gonna be chaining so many promises today, I do want to belabor this point for a little bit, just so we can fully and completely understand what's happening.
[00:01:41] Promise.resolve It's kind of a helper, in this case. Promise.resolve will take 2, and it will effectively return a promise that is immediately resolved with, anyone wanna take a guess?
>> Speaker 2: 2?
>> Steve Kinney: 2, right, so if we said then, and console.logged it, we would get that n as 2, right?
[00:02:00] So no surprises here. And just as we showed in the last slide, we could return n + 1, we'll get 3. We can multiply that by 2, and get 6. And each time it goes through the chain, we're getting the last result out. All right, we can console.log it again, and now it's 36, cuz we went to the second power.
[00:02:18] But if we took that original promise, that promise to resolve 2 again, we stored it? We stored it in the state it is when we put it in that variable, so it's 2, right? So we started over, still 2. So it gives us a chance to effectively work with asynchronous values on our own turf.
[00:02:39] And a little bit more as if they were synchronous code. And there are great features coming to a language that take promises and generators and try to do some hand waving and hide the asynchronous parts away from you, so it looks a lot more like synchronous code, and it's basically built on top of promises.
[00:02:54] 99% of the time, how do you know you have a promise? Because someone handed you a promise, right? 99% of the times you are a recipient of somebody else's promise. You are recieving the promise, you are not making them. But there are cases where you might want to make a promise.
[00:03:11] A really great example, you're dealing with some kind of API, and that API takes a callback. But the rest of your applications, right? Whether it'd be using the modern web technologies and progressive web apps, your framework of choice is expecting promises. So you might have to do the labor in taking a callback and wrapping it in a promise.
[00:03:35] When you do that luckily you are helped out by the browser which has made a promise instructor. So you wanna make a new promise? Good, let me introduce you to new promise. New promise takes a function, which is okay, how does this promise work? What are the mechanics of this promise?
[00:03:55] What does it mean to be resolved or rejected, right? By definition, we looked at that $ajax1 or getJSON, what did it mean in that case? Well, did you get back at 200 in some data? Then things went well. Did you either, network request timed out or you received a 400 or 500 of it, things went poorly, that's what it meant to resolve a rejected.
[00:04:15] But depending on what you're working with, those could mean different things. If you're wrapping a node API, it could be writing to the file system. Did you catch an error? Okay, then something didn't work out. It's gonna be very customized to your use case. So when you pass that function, the promise constructor gives you a resolve callback and a reject callback.
[00:04:36] You inside of this function deal with all of the inner workings of what it means to be resolved or rejected. And when you figure that out, you simply pass the value that you would like to go into the .then, into resolve. Or if things went wrong, you pass the thing that went wrong into the reject, and you'll be able to catch that error and deal with it, right?
[00:04:55] Well, actually be able to do a little bit of this today. But again, I want you to catch this with this syntax looks a little squarely to you. One, will get to practice it. Two, 99% of the time you will be on the receiving end of promises. Somebody else will have done this.
[00:05:09] All right, need so we've passed some numbers to some promises. That's really great. What is this actually look like in practice and an application? All right, so here's our thought leadership blog again. You just showed me this slide, I'm building to something here. We could have a function that renders a post, right?
[00:05:27] It take some object that's got a title and it's got a body and we want to wrap it in the dom like ceremony so we can put it on the page. If we were working with promises we could say that might shorten my render post method up there, cuz I got some big fonts right now, today.
[00:05:45] What we say is, hey, request. When you receive all the posts, use a map to like take the array of posts and turn them all into the dom, so we can put them on the page. And next you could then take those rendered post, and do the next thing, append them to this part, append them to the side bar, append them to the main body of the page.
[00:06:04] You can kind of slowly build up the chain of actions. And if you name these functions really well, you can have something like request post, then render post, then add post to page. And the best thing you wanna do, the most important programmer in the world, is you six months from now.
[00:06:21] When you go to getlame, who wrote that terrible piece code, and you have to stare at yourself in the mirror, and realize it was you, that had all that context loaded in your head. And now six months later, you don't, and you get blaming yourself for things. So it's really like a great API for writing our code in a way that kind of reads like a resume request posts, then render them, then add them to the page.
[00:06:44] Again, we briefly mentioned catch, but we haven't really seen it in action yet, right? In this world, we had a perfect network no matter what, we're going to get posts back from it. If only, I mean, if that would happen all the time, I probably wouldn't have a job.
[00:06:58] The web is hard, hence, we are all employable. All right, so here we say we'll take our Promise.resolve(2), we'll add one to it and then let's throw an error. No reason, right? It's Thursday, we throw errors on Thursdays. And then we'll have the .then console log. In my day, after walking uphill to school both ways, if you did not catch a error in a promise, it just fell silently.
[00:07:28] And you would lose the better part of your morning, trying to figure out why is nothing working. Recent versions of Chrome, Firefox, and Node, if a error is thrown at a Promise and you don't do anything about it, it will at least yell at you. Your code won't break, so if you don't check the console it's still blissful everywhere.
[00:07:45] But previous to that, if you did not catch a promise it just went into the ether. Which is where I like most of my problems to go, except when I have a deadline. So in this case we can catch the error. And you'll notice that my catch is on line 5 but the error happens on line 3.
[00:08:02] As long as you have a catch somewhere in that chain, right? You'll catch everything that goes wrong before that point in that chain. Line 4 will never get called because things went poorly. We'll kind of skip to line 5, right? Bad things happened to line 3, do not pass go, do not collect $200.
[00:08:21] Skip line four, let's deal with that error, and then get back to work. In this case, we got a little too excited and we tried to catch that error before it even happened. We're back to the situation where the error would have gone uncaught.
>> Steve Kinney: All right, there is a situation though where you do wanna put a catch in the middle, it's not always always put it at the end.
[00:08:45] It is most of the time put it at the end because again you're usually on the receiving end. You just wanna know, hey, I need to display some UI to the user. Things went poorly, I'm gonna try again. Do you wanna try again? Depending on the nature of your application.
[00:08:58] But here's a little bit of an extra example. Here in the first .then we're gonna throw in an error we're gonna catch it, we'll consult error it, because why not? Let's just put it where only a developer can see it, the user doesn't need to know. But then we can return and when we return in a catch that gets wrapped into a promise that immediately resolves which is happy land which means you can chain a .then to it.
[00:09:26] So it means in this case, we can have an error, catch it, deal with it, and get the chain moving again. So this is effectively what it would look like, right? We execute it, we did see the console error, but then we did execute the next line, where we took that error and we started with it again, right?
[00:09:43] Cuz there are some cases you're like, listen, I know this went wrong. I have a backup plan, execute the backup plan. A hint, we're gonna build offline apps. Sometimes you wanna go to the network. Sometimes the network is not there. Sometimes you have a backup plan, just to like foreshadow things that are happening today.
[00:10:02] And with that, we're gonna take a minute and turn it back over to Mike and he's gonna talk a little bit about using promises and action with JavaScript workers.