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

The "Events + Promises" 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 work well with asynchronous events that occur once. A stream of events, however, make promises more difficult to use because a promise can only be resolved once. Kyle explains a few of the ways promises could work with event streams but stresses the need for and alternative solution.


Transcript from the "Events + Promises" Lesson

>> [MUSIC]

>> Kyle: Time to move in to some really brain bending stuff. If you thought the stuff that we went over was brain bending, buckle up your seat belt. Concurrency. That's what we've been talking about this entire workshop. What was the poor man's definition for what I meant by concurrency?

Basically, managing the flow control. Managing all these things that are happening and responding to things in the proper order. We know that Promises work when there's a single request and a single response. What happens when the source of our information that's coming, is actually a repeated stream of information that's coming?

Can we wire Promises into an event stream, for example? Because frankly speaking, if we really look at it, most of the asynchronicity that's happening in our programs is actually event oriented. All of our UI is almost entirely event oriented. It's events coming from the server. It's events coming from the user.

We have events everywhere. Soon as you start trying to plug Promises in you might start to see some issues. Let me try to illustrate that for a moment. Let's say that I had a button on my page and I wanted to represent the click of that button by way of a promise.

I already know I can construct a promise like I'm doing on line 1. And I can set up my click handler inside of it. I have button dot click. And I'm doing some extra logic just to illustrate that there's extra steps that we might use, I'm going to test its class name and if it matches that regular expression FUBAR then I'm going to resolve the Promise.

Otherwise I'm going to reject the Promise. And then down somewhere else in my program, line 13 represents a different place in my program, I'm going to respond to that Promise by printing out whatever was clicked on. Now the spirit of this is that every time I click on the button, I'm going to get either that I printed it out or if I clicked a button that, I'm going to print out a className if it matched FUBAR but if I clicked a button that didn't have that, nothing would happen.

That's the spirit of it. Does anybody spot a problem with this code? What?
>> Speaker 2: It's only gonna fire once.
>> Kyle: Promises can only be resolved once. The very first time you click a button, whichever button it is, it's going to resolve or reject the Promise. And every time else when you click the button, nothing's gonna happen.

Uh-oh, what do we do? How do we use Promises, we've built ourselves up to Promises and generators. We've given ourselves several layers of higher order abstractions. But now we're faced with an extremely common thing that's gonna happen in our programs that is responding to events repeated things that are happening and all of sudden Promises seem to fall apart.

What do we do? Well, one thing you might do is to invert. You might say instead of creating my Promise and then my button handler inside do it the other way around. Make my button handler, click handler and then create a Promise inside. What's gonna happen here is I'm gonna get a whole new Promise for each event that's fired.

That sounds great. Except, why? Because once the vents already been fired, then what's the purpose of the Promise here. You see what I'm doing? I'm immediately resolving a Promise ,and then immediately calling a dot then on it. How much sense does that make? There's something even deeper though, because what we've really done when we inverted, we made that little simple trick where I inverted it and I did one inside the other instead of the other way around.

Now we have conflated our separation of concerns. In the previous code, subtly I was able to set up my source in one location and have my response to it. I was able to subscribe and I have my source to it in a different location of my application. Those are two separate capabilities, but when I invert, guess what's happened?

I have to set up the source and the subscription all in the same spot. I have conflated those two responsibilities together. And you gonna have to jump through a whole bunch of hoops to get those Promises out of your click handler. Every time he fired if you need those Promises to respond in other places you're gonna have to save them off into some shared closure variable or some ridiculous thing.

And all of a sudden you're going to be way back, right back at the beginning all the same problems of weirdness and hard to understand code. Right off the bat we see that Promises at least by themselves, are not going to model well in an event oriented world.

We're going to need something better. Now you could observe that actually that wasn't fundamentally an asynchronous set of steps anyway. And we could fall back to things that are a little more familiar to us like a list context where I put my event into an array as I'm doing on 3 three and then I call maps and reduces and filters.

You might go back to a synchronous programming mindset and say, who cares about the promise. But we've still fundamentally got an inverted system here, where the response to the event has to be conflated with the setup for the event. We have producer and consumer in the same spot.

And that's not what we want. We need something to bridge the gap so that we can separate those concerns.

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