Rethinking Asynchronous JavaScript

Promise Flow Control

Kyle Simpson

Kyle Simpson

You Don't Know JS
Rethinking Asynchronous JavaScript

Check out a free preview of the full Rethinking Asynchronous JavaScript course

The "Promise Flow Control" Lesson is part of the full, Rethinking Asynchronous JavaScript course featured in this preview video. Here's what you'd learn in this lesson:

Promises manage sequential flow controls through chaining. Promises are chained together when one promise returns a subsequent promise in its success handler. Kyle shares a few of the previous code examples reimplemented with promise chaining.


Transcript from the "Promise Flow Control" Lesson

>> [MUSIC]

>> Kyle Simpson: So it really is an uninversion of control. Now there's more to promises than that. And this does start to get a little bit more into how do I use the API? This is normally where people start learning promises. So I'm not neglecting teaching you that part, but you'll notice that I built us a foundation of concept first.

Now that you understand why promises are so important. Now you understand that the way that they're designed is intentional, it's on purpose. There's a reason for it. It's not just that they don't know how to design stuff. So let's talk about what they do in terms of flow control.

Because in our modern JavaScript programs, it's very rarely the case, that we simply have a single step, if then asynchronously. There's one action and then when it's finished we move on. Most of our modern JavaScript programs, most of you that are listening, are probably writing vastly more sophisticated systems.

These two things have to happen, and whenever they finish, I move on to this. And then this third thing fires off here, and then it comes back together. That's called flow control. Managing how all of those steps go through your program is called flow control. We've seen flow control already, we saw it with thunks.

We saw it with callbacks. So what do promises offered by a way of flow control? How do they allow us to do, cuz a promise fundamentally is just an if then, it's a wait for this to finish and then do the next thing. Well that's not useful to us unless there's some way to compose promises together, I used word compose again.

Compose promises together in a way to to manage our flow control. So back to our friendly fun pseudocode. I'd like to be able to do the first thing, and then when it's finished do the second thing, and when it's finished do the third thing, and when it's finished complete.

And by the way if there's any error anywhere along that chain, I'd like to fail out to an error. That's the most basic sense sequential flow control. How do promises allow us to manage sequential flow control? The key characteristic. It's an API design decision. Chaining promises. I have one promise that represents the first step.

Another promise represents the second step. Another promise represents the third step. And in anywhere along that chain, and I'll show you how we chain on it together. But anywhere along that chain, if an error happens, if a rejection of the promise happens rather, we fail out to the rejection chain.

Okay? So chaining promises, here's your key take away to understand how chaining promises happen. The way you take a promise A and chain it with a promise B, is that in the promise A, when you set up event handler for a promise A. In that handler you return promise B.

You return one promise, you return the second promise from the success handler of the first promise. And magically they chained together. It's actually not so magical, it's actually when you implement promise libraries, you find out it's actually pretty complicated to do. But nonetheless it's been designed to do that, we take care of that work for you.

So that all you need to do to make a series of chains, is to return one promise from the success handler of the previous one. So do first thing is gonna give us a promise. We set up a then handler, we do whatever we need to do with that.

And then we call doSecondThing. DoSecondThing makes another promise, and you'll notice that we do, is we return it. And by returning it, it means that the .then handler on line five, which would normally have proceeded immediately after the handler from line two. It no longer is going to proceed immediately.

Instead the .then handler from line five is going to wait for the promise returned on line three. It's going to chain those things together. It swaps it out underneath the covers and handles all that complexity for you. So we can approximate a flow control by chaining our promises together.

Now, this could have been done with thunks and it could have been done with callbacks. We've done this already. A sequential set of steps already, you know what that looks like. And it often does pattern itself in a nested series of callbacks. So one of the big things that people get excited about with promises when they see example promise code, they get excited about this idea that it's not nested anymore.

It's organized into a vertical chain. That is the least important part of promises. Not unimportant. It's the least important part. In fact I'll be honest with you, when I first started writing promises this is all I did. I rewrote all of my asynchronous code using promised chains, I became completely drunk on the idea that that's the right way to write my code.

And upon reflection a couple of years later, I don't really use promise chains anymore, it's the least important part, I could take it or leave it. Because it turns out there's better ways of doing flow control, and we're gonna get to that a little bit later. There's better ways of doing our flow control than a promise chain.

Is a promise chain better than a thunk nested series? Yep. Is it better than whatever the crap we call the callback stuff that we wrote before? Absolutely. It's better. But this isn't the important part. So, give me the immutability and the safety and the trust, and I could leave.

I could take or leave the flow control, the chaining of promises. Now, I'd be remiss if I didn't teach you how they work. So we are gonna spend a little bit of time understanding promised chaining. But I just want you to know where it sits within the whole scope and scheme of what we're talking about.

You're gonna need to understand it, cuz you're gonna write a lot of framework code. There's a lot of angulars and reacts, and all that are out there that are gonna use promise chains. But I want you to remember in the back of your head. Why using those promises is so important.

It really has nothing to do with the chaining stuff. Okay? Here's another example, this one is using delay. So we're actually delaying based upon times, and you could use that for an animation chain for example. People have written animations with delays, and of course, works exactly the same way.

>> Kyle Simpson: Back to that whole calculating the meaning of life thing. Here is the meaning of life represented as a promise chain. GetData(10) returns a promise that 1000 milliseconds from now will resolve the promise. And you'll notice that promises are not just about an if then, but they are about message passing as well.

So when getData(10) finishes, it passes that data along to the next step in the promise chain. And we get it in num1. And then when getData(30) finishes a 1000 milliseconds from now, num2 is called with the value 30. And then when that promise resolves, the answer is given that value.

So the promise chain does propagate data down from step to step to step, which is a really important powerful thing. Promises not only represent flow control, but they are also represent data flow through our steps.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now