Check out a free preview of the full Vanilla JavaScript Projects course:
The "Asynchronous JS" Lesson is part of the full, Vanilla JavaScript Projects course featured in this preview video. Here's what you'd learn in this lesson:

Anjana introduces the concept of time in JavaScript and explains the challenges of asynchronous programming. The browser's event loop is discussed, and examples of how it schedules tasks to ensure the browser remains responsive to user interactions are shared.

Get Unlimited Access Now

Transcript from the "Asynchronous JS" Lesson

[00:00:00]
>> Let's press on to something way more challenging than what we've already done, which, to be fair, before we knew JavaScript would have been tricky. Although there's ways to get around that, but that's a whole other conversation. The concept of time. So fun fact, I was a philosophy major, so if you wanna like, just totally like geek out about like what is the nature of time and our existential expectations, like, I'm your girl.

[00:00:34] But, JavaScript also has its own philosophical interpretation of what is time. And it's a little tricky, at least, in my experience and in I think the entire rest of the web's experience because it is something that we, over the years as a JavaScript community, have come up with, hopefully increasingly useful solutions for, but it is a problem.

[00:01:00] Time is a problem. Is it just me that feels that way? Especially, it's like where did the years go this rate? Okay, so asynchronous JavaScript, we're jumping all the way from the document getElementById to the fancy new features of a very complex syntactic sugar situation that is known as async await.

[00:01:28] Have folks written async functions or used the await keyword to await async functions? Excellent, so reviewing, we declare an async function with the async keyword in front of function. And when we have an async function, like for example, the built-in fetch function, which is part of the browser APIs, which we're going to talk about later, is asynchronous.

[00:01:50] And so we can await it to wait for that value that needs some time to be figured out, which internally is represented by a promise of a value. We wait for that promise to resolve, ideally, it resolves and doesn't reject. And then we can capture that value and use it through the rest of our code.

[00:02:18] So, we're all on the same page? Excellent. But I have a question, why do we have to do all this? Like, what is going on with all this promises and these asynchronous things? And, why can't we just like run the code? Why can't I just say, response equals fetch.

[00:02:41] Like why do I have to await it?
>> Yeah.
>> Pesky users expect to do other things.
>> Pesky users expect to do other things.
>> JavaScript is a single threaded language.
>> JavaScript is a single-threaded language. So yeah, those are simple answers. And correct, but also, like, what is any of that?

[00:03:04] At least when I was starting out in JavaScript, after learning some of the mechanics of, okay, I type this magical formula, and then poof, my web page does what I want it to do, I found it very useful to dig in a little bit to what is happening here and why we need to do this stuff, the async, await, promises, etc.

[00:03:30] So as we said, some stuff, it's just a fact of life. Sometimes stuff takes time. In my life, I feel like stuff always takes so much more time than I think it's going to. And that is generally true around anyone who builds software. If you ask them how long it will take for them to build the given software, whatever their answer is, triple it.

[00:03:49] And that goes for yourself, don't do as I do, do as I say, yeah, me too. Anyways, all right, but as mentioned, the browser needs to stay responsive. If it takes a while to go talk to like the dog CEO API, or whatever fun, the Star Wars API, whatever fun API or whatever it is that I'm doing that takes a long time, that's just life, stuff takes time.

[00:04:17] But I have users, and users don't wanna sit there unable to click on anything or interact with anything else on the page. The browser needs to stay responsive to any events that the user is doing, any interactions that they're trying to make. And, complicating factors, JavaScript is a single-threaded language, which those of us who have a lot more experience in operating systems and lower level programming and things like that can expound upon later.

[00:04:55] But for our intents and purposes, it basically means that JavaScript can only do one thing at a time. It can't simultaneously be fetching this resource and also running an event handler function that I passed in to a listener I set up. So, what does this mean for our lives?

[00:05:18] This is a very exciting drawing I made, about a lot of stuff that is happening when we do stuff in JavaScript. Don't know how to get that to go away, so I'm just gonna move it. Okay, so this is a simplified diagram of what is happening inside of the magical creature we know as the web browser.

[00:05:50] So, inside our browsers, sorry, let me bring my slides back. We have a JavaScript runtime, or JavaScript engine. These are separate entities from the browser itself, which also has its own browser engine that's doing a whole bunch of other stuff we're gonna talk about in a second. But you might have heard of these or be familiar with the V8 engine is what runs in Chrome and also Node, and Firefox has a different engine.

[00:06:27] It's called SpiderMonkey, different JavaScript engine. There's others. All the browsers got their own fun little thing, although it seems like they're, there's increasingly V8 is sort of taking over this space, but in any case. In order to run JavaScript, you need a runtime for JavaScript. So that is part of the browser.

[00:06:47] The browser has this JavaScript environment and inside of the JavaScript world, JavaScript has a call stack. So this is essentially where the code to run a given function, when you call it kind of stacks up and sits at the top of the stack while it's running. And when it's finished, it pops off of the stack.

[00:07:14] And if your function calls another function that calls another function, you get these what are called stack frames, one for each function call, stacking up, so that the function your function called has to return before your function can return. So, that is what we call the call stack.

[00:07:33] We've got these functions kind of piling up. So basically, the functions stack up on the stack in frames, and they run to completion. With an asterisk, literally, and and then they pop off the stack magically when they're done. Now meanwhile, functions need data to do stuff with, right?

[00:07:59] And so all of that data has to live somewhere, and it lives in a beautiful, very tidy place in memory called the heap, which probably looks a lot like my room in that it's just a big pile of random crap. So essentially the heap is a sort of disorganized collection.

[00:08:23] Well, disorganized in the sense that everything is just sort of sitting around wherever. All of these different bits of data, which in JavaScript are objects are just all sitting around in the heap, but they have useful references like variable names and addresses and things like that, that we can then use to do whatever the function on the stacks thinks that needs to do.

[00:08:45] So we talked in the JavaScript first steps course about pointers from a variable to an object that's in memory somewhere. And this is all happening within JavaScript. So we've got the call stack where the function stack up. We've got the heap where data piles up in a big old pile of memory.

[00:09:10] But this is not enough to make a browser run and make the whole web page work. There is other stuff going on. So the browser has a whole bunch of other stuff going on. Like, for example, it's interpreting your CSS. It's parsing your HTML. It's doing all kinds of nonsense.

[00:09:34] It's reading your operating system and what you got going on in your, which media devices you gave a permission to, which we're gonna talk about later, etc. But for our intents and purposes as JavaScript developers we care most about a couple of things that it's doing. So the problem, again, is that some stuff in the browser takes time.

[00:09:55] Like for example, Fetch. Fetch is what we call a browser API. We access it from JavaScript, but the browser is really what knows how to fetch something, how to fetch a resource, which you can also see all of those network requests in your network tab in the DevTools, yeah?

[00:10:11] So what happens is, if something takes a long time to complete, we don't want the browser to frees up because JavaScript, with its one little thread, is still doing something, still fetching, or still, I don't know, running some very complex math equation or something. We want that browser to stay responsive.

[00:10:38] So the browser has a little queue where essentially schedules like, this is the next thing that you should do JavaScript when you have a second. So kind of like a little like a to-do list for the JavaScript engine. Like okay, when you get to it, can you please go to the store and grab some milk?

[00:11:00] Thank you. [LAUGH] So what we've got is a queue where these messages kind of get in line. And each of the messages is basically going to say to JavaScript, hey, this function is what I need you to put on the stack next. But we can't just Willy nilly be throwing function calls onto the stack because other stuff is already at the top of the stack, it's running.

[00:11:30] So if I throw something on top of it, then JavaScript would be running that, it runs whatever is top most. And it don't only run one thing at a time. So if I were just chaotically throwing new function calls onto the stack at random times, everything would become chaos, and we would live in a nonsense, abstract universe of just particles swirling around in the ether.

[00:11:53] Wait. Okay, so the the point is that there needs to be some way to sync up this message queue with what's happening on the stack. And that is what is called the event loop. Very simple but crucial part of this whole equation, where essentially the browser is running a continuous loop that's checking the queue for any to-do items.

[00:12:18] And if there's a to-do item, and the stack is empty, it's going to push that next stack frame onto the JavaScript stack. It's gonna give JavaScript a task to do. But it's going to keep checking as long as it needs to for the stack to be ready to accept that to-do list item.

[00:12:41] Just like you see someone carrying a big pile of grocery bags and stuff, you don't wanna be like, yeah, can you also go get some milk right now? No, it's how you make enemies, or so I hear. [LAUGH] The event loop is this very simple loop that's essentially running and constantly scheduling the to-do items that the browser or sorry, it's executing or getting JavaScript to execute the to-do items that the browser has been kind of queuing up or scheduling to happen.

[00:13:15] So, this is all a kind of a very high level overview, a very simplified overview of some of the things that our browsers are doing all the time while we're looking at cat memes. And the event loop is one of those things where, well, this whole model of the queue and the stack and all of this stuff has some interesting implications for how time feels in JavaScript.

[00:13:49] And sometimes we get unexpected results in terms of things running before or after we expected them to because all of the details of this are largely obscured. And like I, for example, was writing JavaScript for quite a while before I understood this at all. And would I say that I 100% understand everything about what's happening in a web browser?

[00:14:10] Again, absolutely not. There is so much happening in a browser, it is one of the most complicated programs, I think, that we generally use every day. And there's a lot to learn about it. So good, there's an image, okay. So the idea is that now you know everything about the browser.

[00:14:31] No, one does not simply completely explain complex situations with a single diagram or meme. But don't worry, I don't have a single meme in these slides. As I have many, many memes, which hopefully will be loading appropriately. But if you would like to dig deeper, I recommended this talk also in the JavaScript first steps course, but this is an amazing talk on YouTube by Philip Roberts called What the heck is the event loop anyway?.

[00:15:02] It's from, I wanna say, 2015 or something around there, and it's a really, really great, much more detailed, much more thorough explanation of all of the stuff we just talked about.