Rethinking Asynchronous JavaScript

Messaging Questions

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 "Messaging Questions" Lesson is part of the full, Rethinking Asynchronous JavaScript course featured in this preview video. Here's what you'd learn in this lesson:

Kyle spends a few minutes reviewing the way generators send and receive messages. He also answers a number of audience questions about generators, iterators, and the use of the yield keyword.


Transcript from the "Messaging Questions" Lesson

>> [MUSIC]

>> Kyle Simpson: I'm gonna run through the arrows at least one more time, cuz I know it can be kind of confusing, all right? Yes?
>> Student: At this point, it said meaning, it's printed out meaning of life 42? Or it said-
>> Kyle Simpson: After line four runs, we return the value out, and it would say meaning of life, colon, 42.

>> Student: 42, but run is not done yet.
>> Kyle Simpson: The generator would still be in a paused state.
>> Student: Yeah, sorry, the generator is not done yet.
>> Kyle Simpson: Which actually brings up a really good point, I'm glad you asked that. Generators do not have to ever finish. It's entirely okay for you to only partially consume a generator.

And then when you have no more reference to it, it's just gonna get garbage collected like any other value. Okay, so it's entirely okay to do that. As matter of fact, sometimes you're going to design your generators to never finish. You know how bad it is usually looked at to put a while true loop in your programming?

Because while true is like, unless you have a return or a break in there, a while true is gonna run forever, right? Actually it turns out if you put a while true inside of a generator and you have a yield keyword in there, that's an entirely valid design that you actually do pretty commonly.

I like to say that generators are putting the while true back into programming. Right? Cuz you might wanna generator that every single time you call it, maybe the while true loop, it's going to generate a new unique ID every time. So every time I call next, I get a new Unique ID and then it loops back and it waits again till I ask for another value and another value.

That's thinking of generators in the way that, where their name comes from, that they are generating or producing values for us from the outside world. So that's thinking about a generator is a producer and I'm going to consume it by calling dot next. From the asynchronous programming world, I've asked you to flip your brains back the other way.

So I've asked you to think more about the inside of the generator, and not worry about what's happening on the outside. But that's where generators get their name, is that they produce an iterator that can be can be consumed.
>> Student 2: Quick question, why do you put parentheses around the yield keyword?

Does that do anything?
>> Kyle Simpson: Grammatically it's required.
>> Student 2: Okay.
>> Kyle Simpson: There are some weird grammatic surrounds the yield keyword. So without getting on too much of a rabbit trail there, if you study the ES6 grammar, the way yield is expressed, in this particular case it's required. So that's an unfortunate nuance of grammar.

>> Student 4: There's a couple questions there, saying what is line three waiting for? He thought you mentioned that line three is waiting for ten to finish.
>> Kyle Simpson: No, so let me run through the arrows again and see if that answers that question. After line five, none of the generator has started.

We have an iterator for it, wrapped around the function we call run. But it hasn't run yet. Nothing has happened. I could have called run. I could have called it step, if that helps you understand it better. Cuz stepping is going to step through it one at a time, okay?

So we call line seven. We step into it, or we start the running of it. We run the first part of the generator and that's gonna transfer control to line two. Line two starts to execute, runs across a yield keyword and says, I need a value here, I'm going to wait.

So I'm gonna return control and pause myself while you get ready to answer my question. And I'll wait as long as it takes. In this case we synchronously have an answer. We're going to send an answer right back in with the value ten. So the value ten is an actual JavaScript number, there's no specialty to it, it's just a number that we pass in.

Could've been a string, could have been an object, could have been anything. But it's a value that we pass in and now it gets added to one and x equals 11. Then we move on to line three. Don't get confused by the arrows we're still running the generator.

We're on the line three. We start to run line three we have var y equals one plus. And oops, there's another yield. So we need to pause again waiting for control, so we are going to return control to line eight. Which would mean that line eight would get an object back with value undefined under false.

At some later point, like line ten, we're going to answer the pending paused question. The yield keyword from line three is waiting for an answer, and we're going to give it that answer by passing in the value 30. So the answer to the question is, what is line three waiting on, it's waiting on the value 30 from line ten.

Okay, that value comes in, 30 plus 1, we now have 31. X is 11, y is 31. We add those two together, we get the value 42 on line four. And then we yield out that value, 42, back to line ten. It's a pause, resume, pause, resume, pause, resume.

And every pause is asking a question and every resume is answering the question. Does that make sense? Yes?
>> Student 3: So we are paused on line four?
>> Kyle Simpson: We're currently paused on line four. Which is okay, we can leave it in that state. On line 12 you could call run again if you want.

And you could even pass in a value and it would go in, and the way we've written our generator we don't do anything with it, but you could. And you can have a return key word on line four and a half if you want and that would return a value.

That's all totally valid, but it's not required. You can partially consume this generator if you need to.
>> Student: So if you just put the y through around then you could just constantly log the meaning of life. Next, next next, next, next, next.
>> Kyle Simpson: Yep, exactly.
>> Student 3: On line seven if you passed in on the first one, if you're passing an initial value, would it not break on line two?

>> Kyle Simpson: No, that's not what would happen. This is one of the.
>> Kyle Simpson: Not so wonderful parts of the design. As a VS6, if you pass in a value to the initial dot next call, there is no yield keyword waiting for it. So that value just goes. Okay? Which is weird from the outside perspective.

It feels like there ought to be some way to get a hold of it, and there is no way to get a hold of it. Many people including myself brought up concerns about the inconsistency of that design quirk, thinking that that would confuse people. There's a proposal ES7, of a way that you would be able to get access to that value, not through a yield keyword.

But at the moment as it stands, don't send a value to the first dot next call because it's just going to go [NOISE]. That's an unfortunate, weird quirk of the design.
>> Student 2: On line four, if you just do a return of x plus y, wouldn't that finish also?

>> Kyle Simpson: It would still do the exact thing.
>> Student 2: Okay. Then the-
>> Kyle Simpson: But the generator would be fully complete.
>> Student 2: Would be complete.
>> Kyle Simpson: Yup.
>> Student 2: Okay.
>> Kyle Simpson: That's exactly right. Okay, in the back.
>> Student 4: They're asking in the chat, on line two., if that takes a long time before reaching yield, but then you call run, but a call to run happens before that finishes, what does that look like?

>> Kyle Simpson: That's not possible with JavaScript single threaded semantics. It's not possible for you to try to start the generator twice, unless the generator from inside of itself tried to call run. And if you did that you're gonna get an error. But it's not possible for some other part of your program to try to call run again.

Because at any given moment only one line of JavaScript is executing this is all still fundamentally single threaded.
>> Student 4: And then they're also following up with, use of a generator, can you us some real world examples?
>> Kyle Simpson: We're getting there with the asynchronous pattern. Okay, he real world example I'm going to give you is how this is going to totally magically transform all of our asynchronous programming.

But there are other use cases besides asynchronous programming, the most common of which is to produce values as I was talking about. Flipping your mindset back to not worrying about the inside and worrying about the outside. A generator is just a way to produce an iterator. And if I wanted to iterate through a set of values, I could have my generator sit there and loop and yield those out to me.

A generator is a way to iterate over an object, for example, I could have an object that's a data structure, with a bunch of values in it, and I could define a generator as my iterator, and just yield out all my own values in some special way. So there's ways to use generators as iterator producers.

I think that's the less interesting usage of them. I think the asynchronous pattern that we're heading towards is the more interesting usage.
>> Student: Can you make it immediately invoking to do that first one for you?
>> Kyle Simpson: Can a generator be an iffy? Absolutely. But you're not gonna wanna make a generator an iffy unless you store that iterator because you're going to need that iterator for later.

So yes.
>> Student 4: So just kind of clarifying then, they're saying, so the run is blocked until yield?
>> Kyle Simpson: That is correct. Just that standard old, outside of the generato,r everything's the same as it always was in JavaScript. Single threaded. When a call's running, nothing else can run.
>> Kyle Simpson: The only thing that changes is what happens on the inside, the ability for it to pause.

>> Kyle Simpson: Okay. So let's try to drive more, keep your mind set up based on the inside, and don't worry so much about the stuff on line seven through 11. Cuz that stuff is gonna end up being plumbing that's hidden away in a library. The stuff we're gonna care about is the stuff that's inside of the generator, okay?

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