Transcript from the "Reviewing Promises" Lesson
>> Steve Kinney: Hello everyone. My name is Steve. I'm a senior front end engineer at SendGrid. We'll talk a little bit about Promises. Disclaimer, Promises are not specifically a progressive Web App technology. However, they are littered throughout progressive Web Apps. A lot of the other technologies that we're gonna be using throughout the rest of this workshop will use Promise-based APIs.
[00:00:26] So it makes sense to spend a little bit of time just getting us all kinda caught up to speed on what exactly a Promise is, and how they work, how to make them, how to receive them, how to use them, all sorts of fun stuff like that. So here's the high level.
[00:00:40] Promises can be thought of as an eventual value. You can almost think of it at a very high level as an IOU. Like, I don't have your money yet, here is this piece of paper that signifies one day I may or may not pay you. They are an abstraction around dealing with asynchronous programming, right?
[00:00:55] If you think about it on a network level, okay, get me that thing from the server, great. That's not instantaneous, we don't have it yet. We have to send out a network request. There's even like the speed of light is a limiting factor at that point. But we wanna know when we do hear back from the network, we wanna know what that value's going to be, so we can begin to work with it.
[00:01:14] A Promise could come back from the network with stuff. It could also not, right? The network request never makes it there. The server says thanks but no thanks, or you asked for the wrong thing. Right, there's two eventual values that we can get to, we'll talk in a second, but high level, good and not so good.
[00:01:34] You might have already used them. There are a lot of Promise based APIs in the wild. This pattern has been around for decades. It's just getting a lot more popularity now in the client side web ecosystem. If you've ever used the $.getJSON, right, you can give that a callback.
[00:01:49] You can give it an object with a bunch of options in it. But if you just assign that to a variable, it effectively returns a jQuery.Deferred, which, for our purposes, is like a Promise. Yeah?
>> Speaker 2: Are you calling callbacks and Promises basically the same thing?
>> Steve Kinney: No, so callback, you pass in a function.
[00:02:07] You're saying hey, I'm going to ask you to go do this thing. When you're done, take this function with you, call it, right? When we get it from a Promise we're saying, hey, do that thing, give me something to hold onto while you go ahead and do it, and eventually, we'll be that.
[00:02:21] So it's kind of the control is in the opposite of directions, right? We're giving away our function, versus we're receiving a value that has not come to be just yet. Cool and for our purposes, taking control on our side where we can do things works out a lot better than callbacks, which you can only have called once and stuff along those lines.
[00:02:42] And we'll kinda see as we get into the examples. All right, here is a mental model. You have what we'll call Schrodinger's mailbox. Inside of Schrodinger's mailbox, you either have that check you've been waiting for, or an explosion emoji. So there's a firecracker in there, or there's some bills I guess, either way, it's great.
[00:03:05] When we first make the network request, we don't know. We don't know whether or not we're gonna hear back from the network or not, right? We say that's in its pending state. The electrons are going through the copper wire, they're headed towards the server to find out. They're coming from, what was it, Dulles, Virginia, that web page test starts?
[00:03:23] They're on their way to Minneapolis. They haven't made it there yet, we don't know what the end result is gonna be. That's when the Promise is in its pending state. If we hear back, we know that the Promise has resolved. Here is the data that you requested from the server.
[00:03:37] If something blows up along the way, the Promise is said to be rejected. Once it moves into either the resolved or the rejected state, that's it. The Promise is done, you've gotten your value or your explosion in your mailbox, either way. But we have reached a conclusion, we now know what is in the mailbox.
[00:03:54] There's no closing the lid back on the mailbox and starting over again, right? So a Promise is pending, and then it reaches one of these two states and that's where it stays. So the basic use, right, if we look at that top line there, we can say that we getJSON, we assign it to a variable.
[00:04:11] Again, if you're using callbacks, you would give a function as another argument, you'd give your function away. Here, we're saying give me the eventual value. With that, we can say, go to the network, and it's almost like thinking about it in English, right? Hey, make this network request, then, right, and the then method will be when the promise resolves.
[00:04:30] If everything works out great, then do this, right? So when our eventual value is no longer eventual and it's just a value, we're able to pass it into the callback, effectively, in the then method. If things go wrong, we catch that error and we can either do something with it or show the appropriate UI, like hey, that network request you made didn't work out so great, here's the error message.
[00:04:55] Versus, we did hear back from the network, great, here's the data that you asked for and we put it on the page.
>> Steve Kinney: Finally, is in the spec, but it's not actually shipped yet, there's a lot of things you might wanna do either way. Mike talked before about putting up a loader, that's a great UI pattern.
[00:05:14] For some reason, users really enjoy seeing an indeterminate spinner that doesn't mean anything, versus nothing, right? Or a progress bar that just keeps going, that has the stripes that just keep moving along. It's not actually moving towards anything. Users love that. And so whether the request comes back successfully or whether it fails, you probably want to get rid of that progress bar.
[00:05:35] This is a stage three in the proposal process which means it is likely to be implemented but hasn't just yet. But this is just one other thing to kind of be on the lookout for. Either way, you can see that this has happened when the promise has been just effectively settled.
[00:05:56] Interesting thing about Promises is that they can be chained. So you can say .then(), you get the value from the Promise, and with this case, we're imagining it's a network request. So you'll get the data you got back from the network, it will be the value in there.
[00:06:12] You can do some stuff, right, that's a very technical term. You do stuff, right, and then you can theoretically pass that to another .then(). If you have a Promise again at the end that goes into the next .then(). But if you use a regular value, like a number or a string or a JSON object or a boolean that would effectively be wrapped in a Promise and passed to the next one and this seems like okay, neat.
[00:06:38] But it allows you to keep chaining .then() .then() .then() without worrying about like did I return a Promise? Did I actually return some other kind of value? They'll effectively be wrapped in the Promise that for our purposes immediately resolves. Like we don't have to wonder if a 2 is going to end in some kind of error.
[00:06:53] We're gonna know it's gonna be a 2. So this is kind of what it'll look like in practice. We saw that $.getJSON from some endpoint. This could be like your thought leadership blog that you've been working on. Or you're gonna shift some paradigms, make some tastes. We can request from that endpoint, and we're gonna get back, we haven't heard back from the network yet.
[00:07:14] Cool, so we hold onto it. When we get it, we can start by console logging it, or you could also take that same Promise cuz it's already resolved. Both of these will fire effectively at the same time, technically not at the same time, but effectively for our purposes at the same time.
[00:07:29] You can do multiple things with that data. With a callback, you would have given away that function. You would had to do everything in that one function cuz it would have been called when the network request came back. So Promises are cool, because you can take that value and do multiple things.
[00:07:42] That value is under your control, rather than you giving away the function.