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

The "Concurrency" 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 introduces concurrency as two higher-level tasks happening within the same timeframe. He illustrates these higher-level tasks or macro-tasks might be composed of many micro-tasks. As each micro-task is initiated, it queues up behind any other existing tasks and is executed in order.


Transcript from the "Concurrency" Lesson

>> [MUSIC]

>> Kyle: That brings us to this idea of concurrency. What does concurrency mean? A lot of people think concurrent means two things happening at the same time. Again, it's one of those things if you squint at it you might say, yeah, maybe they're kinda like the same but there's an important nuance difference here.

And by the way, if somebody wants to object to my particular usage of the words, there's actually lots of different meanings for these words. And it's hard to nail down one particular thing, so I'm trying to be is consistent within my own usage of these things. But there's actually, if you go and read Wikipedia pages or other text on it, you'll find a whole range of different opinions on these things.

But my way of explaining to you what concurrency is rather than saying with parallelism two things are happening at the exact same instant, I would describe concurrency as two higher level tasks happening within the same timeframe. So rather than an instant, we're going to look at a timeframe.

We're gonna say within this timeframe, two higher level operations are going to occur. To understand the notion of higher level items or higher level operations occurring, we also have to understand that higher level, or what I might call macro level tasks can be broken up or thought of as being broken up into micro level tasks.

So here's a way to visualize the macro level and the micro level, and how these things might go together. So the left-hand side we have this yellow orange task, with a macro level task. Which is broken up into those individual numbers, 1, 2, 3, 4. Which would be micro level tasks.

These are my made up terms, these aren't official terms. But macro level and micro level tasks. And then, on the right-hand side, we have another macro level task represented by that blue green color, and it's broken up into three pieces, 1, 2, 3. Now, for the easiness of math I'm going to pretend and assume that each one of these micro level tasks takes one full second to complete.

So this overall system to do all of the tasks it's going to take seven seconds, does everybody agree with that?. Cuz it's a single threaded system. Now, that could happen at exactly the same moment. So those one second micro level tasks are going to have to be scheduled in some way that all seven of them finish and that's gonna take seven seconds.

Let's pretend that the yellow orange represents an Ajax request and response cycle. Fire off a request we get a response back and let's pretend that the blue represents a scroll that we scroll on the page and it repainted everything because we scrolled to a new location of the page.

These two operations have to fundamentally happen on the same thread. The entire user interface of our browser is happening on the same thread so our JavaScript, the garbage collector the style engine, the repaint, everything, it's all happening on one thread which means we kinda have to worry about contention and if you've ever had an animation on your page have jitter in it.

You know why that happened? Because something contended on the UI thread at that moment your CSS engine was trying to your style your layout engine was trying to repaint the page. It's a 60 frames a second way that it's repainting your page. It tried to do that but at that exact moment something else was running.

So I had to wait an extra moment and that's what created that jitter, single threaded. So if we have these higher level, macro level tasks that we want to happen concurrently. I want the yellow and the blue to happen at the same time. Why? Well, let's imagine they don't.

One way of scheduling this system, one way of scheduling this program is to do all of the yellow first and then all of the blue. What would that look like on our page? Ignoring the one second thing for a moment, what it would look like on our page Is that it would look like I click the button to make an Ajax request and while that was happening I tried to scroll my page but everything was completely frozen while that happened.

And then, after it finished then it sort of jumped back and caught up. Ways I precedent for that It's called synchronous XHR, synchronous Ajax. One of the worst evils perpetrated upon the web platforms. Terrible idea. There are people out there that are crying and literally complaining on standards list saying, how dare you take away my synchronous XHR?

It's been deprecated and removed from the web platform because it's a really bad idea. It's a terrible idea to schedule it that way isn't it because even though the overall system would still take seven seconds that particular choice of scheduling those micro level tasks. Would feel terribly inefficient does somebody agree with that just from a user experience perspective.

If on the other hand we chose to interleave these things together. Where one thing might be blocking so we can do something else while one thing is blocking before it can move on to the next thing, if we chose to schedule those things in an inner leaved fashion, the overall system might still in fact take seven seconds.

But the perception of the performance is that things are gonna be happening in parallel really more importantly we should be saying those things are happening concurrently. The Ajax and request and response is happening concurrently with the repainting. Even though at any given instant only one of those micro level tasks is occurring.

So just to visualize that my fancy animation took me about two hours to get right in Keynote, here's a way of scheduling those micro level tasks onto that single thread in the middle called the event loop. I don't know why it advance, the single thread in the middle called the event loop that's what we call it in JavaScript.

At any given instance only doing one of those things. So when you have an Ajax request that comes back and you need to fire the cal back for a response. If at that moment somebody is already executing. Nobody gets to cut in line. It's not like your response callback gets to interrupt and say, it's time for me to run.

You know what it does? It gets at the end of the line just like everybody else. So when the garbage collector says, I need to collect some garbage. And the style CSS repainter says, I need to repaint the page. And the layout engines says, I need to do some work.

And the JavaScript engine, says I need to fire this response call back in every single one of them. It's a first come first serve, everybody gets at the end of the line. That is fundamentally what the event loop is. Such is the high level view to help you sort out what's going on.

And the main point here is that the scheduling of this is not always entirely within our control. Sometimes it's race conditions that choose one versus the other happening. Not all that's happening, but there's an awful lot of coordination necessary. Sometimes it's the coordination of when things happen, but oftentimes it's the coordination of responses to things happening.

Cuz it's not always a very serial, like do this and, and when that's finished do this and then when that's an issue that oftentimes it's much more complex like hey go do these three things in parallel. And then, when at least two of them have finished you can move on and do this other thing and then when that third one comes along you can branch out here and do this other thing.

And before long. It's just crazy complex tree of different states of things that could happen, and it's that complexity that we have to manage in our programs. It's that complexity that begs for us to have better patterns for concurrency management. That's what asynchronous programming is, managing our concurrency.

So that's a motivation for you from a philosophical and conceptual basis of the motivation for why we go to the lengths that we do to try to write the programs that we do. Everything that I'm gonna show you in this workshop is something that could fundamentally be done with nothing but the callback with no new functionality.

But we're gonna see that the callbacks fundamentally are Insufficient for expressing the higher and higher orders of complexity that our modern JavaScript programs are doing. Our modern JavaScript programs are falling all over themselves, because we need these higher order patterns, and we're not disciplined enough to learn them and implement them.

We just keep doing the same thing we've always done, because it always worked, and it always worked, and it always worked. This is a call to arms to say the new baseline of competency as a JavaScript developers is to have a much more sophisticated strategic and tactical approach to your concurrency management, to your asynchronous programming.

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