Placeholder Image

Subtitles section Play video

  • >> (Phillip Roberts) hello, come in and sit down.

  • So for the last session before the afternoon break, we have Phillip Roberts who works at

  • Andea and is here from London ‑‑ Scotland.

  • Edinbrough.

  •  ‑‑ wow, ten second memory, he's going to talk about the vent loop.

  • If everyone could give Phillip a big brownedder round of applause.

  • >> Phillip Roberts: Okay hello everyone, thanks for coming to the side track, it's awesome

  • to see it packed out in here.

  • Can everyone give me a stretch.

  • I needed to stretch, so I look less weird.

  • I want to talk about the event loop and what the heck is the event loop, as in the event

  • loop inside JavaScript.

  • So first up, as he said I work for AndYet which is an awesome little Dev shop in the

  • US, look us up if you need help with realtime stuff.

  • That's what we're good at.

  • So, about 18 months ago--I'm a paid professional JavaScript developer--I thought to myself

  • how does, like JavaScript actually work?

  • And I wasn't entirely sure.

  • I'd heard V8 as a term, chrome's Runtime didn't really know what that meant, what that did.

  • I'd heard things like single threaded, you know obviously I'm using callbacks.

  • How do callbacks work?

  • I started a journey of like reading and research and experimenting in the browser which basically

  • started like this.

  •  ‑‑ I was kind of like JavaScript what are you.

  • I'm a single threaded single concurrent language ‑‑ right.

  • yeah, cool, I have a call stack, an event loop, a callback queue, and some other APIs

  • and stuff.

  •  ‑‑ rite.

  • I did not do a computer science degree.

  • I mean, these words, they're words, so I heard about V8 and the various Runtimes and different

  • browsers so I looked to V8 do you have a call stack, an event loop, a callback queue, and

  • some other APIs and stuff, I have a call stack and a heap, I don't know what those other

  • things are, okay, interesting so basically 18 months passed.

  • And I think I get this.

  • (Laughing) and so, this is what I want to share with you today.

  • Hopefully this will be useful if you're relatively new to JavaScript, help you understand why

  • JavaScript is so weird when you compare it to other languages you might used why callbacks

  • are a thing, cause us hell but are required.

  • And if you're an experienced JavaScript developer hopefully give you some fresh insights how

  • the Runtime you're using works so you can think about it a little better.

  • So if we look at the JavaScript Runtime itself like V8 which is the Runtime inside Chrome.

  • This is a simplified view of what JavaScript Runtime is.

  • The heap, where memory allocation happens, and then there's the call stack, which is

  • where your stack frames are and all that kind of stuff, but, if you, like, clone the V8

  • code base and grep for things like setTimeout or DOM or HTTP request, they're not in there,

  • they don't exist in V8, which was a surprise to me.

  • It's first thing you use when you start thinking about async stuff and it's not in the V8 source.

  • Hmm ... interesting.

  • So, over this 18 months of discovery I come to realize this is really, this is really

  • the bigger picture, this is what I'm hoping to get you on board with today and understand

  • what these pieces are, we have the V8 Runtime but then we have these things called web APIs

  • which are extra things that the browser provides.

  • DOM, AJAX, time out, things like that, we have this mythical event loop and the callback

  • queue.

  • I'm sure you've heard some of these terms before, but maybe you don't quite understand

  • how these pieces pull together.

  • So, I'm going to start from the beginning, some of this will be new, to words might be

  • new to people, other people will get this.

  • We're going to quickly move on from here, bear with me if this is obvious, I think for

  • a lot of people it's not.

  • So, JavaScript is a single threaded programming language, single threaded Runtime, it has

  • a single call stack.

  • And it can do one thing at a time, that's what a single thread means, the program can

  • run one piece of code at a time.

  • So, let's try and visualize that just to get our heads around what that mean, so if I have

  • some code like this on your left, we've got a few functions, a function multiplier which

  • multiplies two numbers, square which calls multiply with the same number twice, a function

  • which prints the square of a number of calling square and then calling console.log and then

  • at the bottom of our file we actually run print square, this code all good?

  • Make sense?

  • Cool.

  • So, if we run this, well, I should back up a step, so the call stack is basically ‑‑

  • it's a data structure which records basically where in the program we are, if we step into

  • a function, we put something on to the stack, if we return from a function, we pop off the

  • top of the stack that's all the stack can do, ‑‑ so if you run this file, there's

  • kind of a main function, right, like the file itself, so, we push that on to the stack.

  • Then we have some function definitions, they're just like defining the state of the world,

  • and finally we got to print square, right, so print square is a function call, so we

  • push that on to the stack, and immediately inside print square, push on to the stack,

  • which calls multiply, now we have a return statement, we multiply A and B and we return,

  • when we return we pop something off the stack, so, pop, multiplier of the stack, returning

  • to square, return to print square, console.log, there's no return, it's implicit, because

  • we got to the end of the function, and we're done so that's like a visualization of the

  • call stalk, does that make sense?

  • (Yes, Phil) even if you haven't thought about the call stack before, you've come across

  • it when you've been doing browserside development, so if we have code like this, a function baz

  • which calls bar, which calls Foo, which throws an error if we run it in Chrome we see this.

  • And it prints the stack trace, right, the state of the stack when that error happened,

  • so, uncaught error oops Foo, bar, Baz, anonymous function, which is our main.

  • Equally, if you've heard the term like blowing the stack, this is an example of that.

  • Have a function foo which calls Foo , so what's going to happen ? We have a function main

  • which calls foo which calls foo, which calls foo, which calls foo, and ultimately chrome

  • says, you probably didn't mean to call foo 16,000 times recursively, I'll just kill things

  • for you and you can figure out where your bug lies, right.

  • So although I may be representing a new side of the call stack you have some sense of it

  • in your development practice already.

  • So, the big question then comes is like what happens when things are slow?

  • So, we talk about blocking and blocking behavior and blocking, there's no strict definition

  • of what is and didn't blocking, really it's just code that's slow.

  • So console.log isn't slow, doing a while loop from one to ten billion is slow, network requests

  • are slow.

  • Image requests are slow.

  • Things which are slow and on that stack are what are blocking means.

  • So heres a little example, so let's say we have, this is like a fake bit of code, getSynchronous,

  • right, like jQuery is like, AJAX request.

  • What would happen if those were synchronous requests, forget what we know about async

  • callbacks they're synchronous.

  • If we go through it like we have, we call getSync and then we wait, because then we're

  • doing network request, network is relative to computers, are slow, hopefully that network

  • requests completes, we can move on, wait, move on.

  • Wait, and, I mean, this network request might never finish, so ... yeah, I guess I'll go

  • home.

  • Finally those three, you know blocking behaviors complete and we can clear the stack, right.

  • So in a programming language is single threaded you're not using threads like say Ruby, that's

  • what happens, right, we make a network request, we have to just wait till it's done, because

  • we have no way of handling that.

  • Why is this actually a problem?

  • The problem is because we're running code in browsers.

  • So, let's you ‑‑ here we go, okay.

  • So this is just, this is Chrome, this is the code I just ran.

  • Browsers don't give us ‑‑ well they do give us synchronous AJAX request, I'm faking

  • this out with a big while loop, because it's synchronous, I basically while loop for five

  • seconds before continuing, so if I open up the console here.

  • We can see what happens, so with request foo.com, why this is happening, I can't do anything,

  • right, even the run button hasn't finished rerendering the fact that I clicked it.

  • The browser is blocked, it's stuck, it can't do anything until those requests complete.

  • And then all hell breaks loose because I did some stuff,it figured that out I'd done it,

  • it couldn't actually render it.

  • Couldn't do anything.

  • That's because if that call stack has things on it, and here it's got these yeah, it's

  • still going.

  • We've got the synchronous request, the browser can't do anything else.

  • It can't render, it can't run any other code, it's stuck.

  • Not ideal, right if we want people to have nice fluid UIs, we can't block the stack.

  • So, how do we handle this?

  • Well the simplest solution we're provided with is asynchronous callbacks, there's almost

  • no blocking functions in the browser, equally in node, they're all made asynchronous, which

  • basically means we run some code, give it a callback, and run that later, if you've

  • seen JavaScript you've seen asynchronous callbacks, what does this actually look like.

  • Simple example to remind people where we're at.

  • Code like this, console.log hi.

  • Write, we run the setTimeout, but that queue's the console log for future so we skip on to

  • JSConf and then five seconds later we log "there" right, make sense?

  • Happy.

  • Basically that's setTimeout is doing something.

  • So, asynchronous callbacks with regards to the stacks we saw before ... how does this

  • work?

  • Let's run the code.

  • Console.log hi. setTimeout.

  • We know it doesn't run immediately, we know it's going to run in five seconds time, we

  • can't push it on to the stack, somehow it just disappears, we don't have like a way

  • of describing this yet, but we'll come to it.

  • We log JSConfEU, clear, five seconds later somehow magically "there" appears on the stack.

  • How does that happen?

  • And that's ‑‑ this is basically where the event loop comes in on concurrency.

  • Right, so I've been kind of partially lying do you and telling you that JavaScript can

  • only do one thing at one time.

  • That's true the JavaScript Runtime can only do one thing at one time.

  • It can't make an AJAX request while you're doing other code.

  • It can't do a setTimeout while you're doing another code.

  • The reason we can do things concurrently is that the browser is more than just the Runtime.

  • So, remember this diagram, the JavaScript Runtime can do one thing at a time, but the

  • browser gives us these other things, gives us these we shall APIs, these are effectively

  • threads, you can just make calls to, and those pieces of the browser are aware of this concurrency

  • kicks in.

  • If you're back end person this diagram looks basically identical for node, instead of web

  • APIs we have C++ APIs and the threading is being hidden from you by C++.

  • Now we have this picture let's see how this code runs in a more full picture of what a

  • browser looks like.

  • So, same as before, run code, console log hi, logs hi to the console, simple.

  • now we can see what happens when we call setTimeout.

  • We are ‑‑ we pass this callback function and a delay to the setTimeout call.

  • Now setTimeout is an API provided to us by the browser, it doesn't live in the V8 source,

  • it's extra stuff we get in that we're running the JavaScript run

  • time in.

  • The browser kicks off a timer for you.

  • And now it's going to handle the count down for you, right, so that means our setTimeout

  • call, itself is now complete, so we can pop off the stack.

  • JSConfEU”, clear, so, now we've got this timer in the web API, which five seconds later

  • is going to complete.

  • Now the web API can't just start modifying your code, it can't chuck stuff onto the stack

  • when it's ready if it did it would appear randomly in the middle of your code so this

  • is where the task queue or callback queue kicks in.

  • Any of the web APIs pushes the callback on to the task queue when it's done.

  • Finally we get to the event loop, title of the talk, what the heck is the event loop

  • is like the simplest little piece in this whole equation, and it has one very simple

  • job.

  • The event loops job is to look at the stack and look at the task queue.

  • If the stack is empty it takes the first thing on the queue and pushes it on to the stack

  • which effectively run it.

  • So here we can see that now the stack is clear, there's a callback on the task queue, the

  • event loop runs, it says, oh, I get to do something, pushes the callback on to the stack.

  • Remember it's the stack is like JavaScript land, back inside V8, the callback appears

  • on the stack, run, console.logthere”, and we're done.

  • Does that make sense?

  • Everyone where me?

  • Awesome!

  • Okay.

  • So, now we can see how this works with probably one of the first encounters you would have

  • had with Async stuff which for some weird reason someone says says you have to call

  • setTimeout zero, ‑‑ okay, you want me to run the function in zero time?

  • Why would I wrap it in a setTimeout?

  • Like the first time you run across this, if you're like me,i see it doing something, but

  • I don't know why.

  • The reason is, generally, if you're trying to defer something until the stack is clear.

  • So we know looking at this, if you've written JavaScript, that we're going to see the same

  • result, we're going to seehi” “JSConf”, andthereis going to appear at the

  • end.

  • We can see how that happens.

  • The setTimeout zero, now it's going to complete immediately and push it on to the queue, remember

  • what I said about the event loop, it has to wait till the stack is clear before it can

  • push the callback on to the stack, so your stack is going to continue to run, console.log

  • hi”, “JSConfEUand clear, now the event loop can kick in and call your callback.

  • That's like an example of setTimeout zero, is deferring that execution of code, for whatever

  • reason to the end of the stack.

  • Or until stack is clear.

  • Okay.

  • So, all these web APIs work the same way, if we have AJAX request, we make an AJAX request

  • to the URL with a callback, works the same way, oops sorry, console log, “hi”, make

  • an AJAX request, the code for running that AJAX request does not live in JavaScript Runtime

  • but in the browser as a web API, so we spin it up with a callback in the URL, your code

  • can continue to run.

  • Until that XHR request completes, or it may never complete, it's okay, the stack can continue

  • to run, assuming it completes, gets pushed to the queue,picked up by the event loop and

  • it's run.

  • That's all that happens when an Async call happens.

  • Let's do a crazy complicated example, I hope this going to work, if you haven't realized

  • all this is in keynote there's like I don't know 500 animation steps in this whole deck.

  • (code blows up, flames animation) (Applause) J Whew ... no ... so ... interesting, we're

  • given a link.

  • Hmm ... is this big enough, can people see?

  • Okay, so basically I wrote this talk for Scotland JS, after the talk I broke half of the slides

  • and could not be bothered to redo all the slides because it was a total pain in the

  • ass in keynote to do it so I took much easier route (Laughing) of writing a tool that can

  • visualize the JavaScript Runtime at Runtime, and it's called loop.

  • So, let's just run this example and, which was kind of the example that we had on the

  • previous slide, I haven't shimmed XHR yet, it's doable I just haven't done it.

  • As you can see the code, we're going to log something, this is a shim around addEventListener,

  • setTimeout and we're going to do a console.log. ‑‑

  • I'm going to run it and see what happens so ... add a DOM API, add a timeout, code is

  • going to continue to run, pushes the callback into the queue which runs, and we're done.

  • If I click on here then it's going to ... trigger the web API, queue the callback for the click

  • and run it.

  • if I cluck a hundred times we can see what happens.

  • I clicked, the click doesn't get processed immediately, itself gets pushed to the queue,

  • as the queue gets processed, eventually my click is going to get dealt with, right.

  • So I have a few more examples I'm going to run through here.

  • Here we go, okay, so, I'm just going to run through a few examples just to kind of talk

  • about a few things that you might have run in to and not thought about with Async APIs,

  • In this example we call setTimeout four times with the one second delay, and console.log

  • hi”.

  • By the time the callbacks get queued... that fourth callback we asked for a one second

  • delay, and it's still waiting, the callback hasn't run, right .

  • this illustrates the ‑‑ like what time out is actually doing, it's not a guaranteed

  • time to execution, it's a minimum time to execution, just like setTimeout zero doesn't

  • run the code immediately it runs the code nextish, sometime, right?

  • So ... in this example I want to talk about callbacks, so, depending on who, speak to

  • and how they phrase things, callbacks can be one of two things, callbacks can be any

  • function that another function calls or callbacks can be more explicitly an asynchronous callback

  • as in one that will get pushed back on the callback queue in the future.

  • This bit of code illustrates the difference, right.

  • The forEach method on an array, it doesn't run, it takes a function, which you could

  • call a callback, but it's not running it asynchronously, it's running it within the current stack.

  • We could define an asynchronous forEach so it can take an array, a callback and for each

  • item in the array it's going to do a setTimeout zero with that callback, I guess this should

  • pass in the value, but any way, so, I'm going to run it and we can see what the difference

  • is, so for the first block of code that runs, it's going to sit and block the stack, right?

  • Until it's complete, whereas in the Async version, okay, it's slowed down, but we're

  • basically going to queue a bunch of callbacks and they're going to clear and then we can

  • actually run through and do a console.log.

  • In this example the console.log is fast, so the benefit of doing it asynchronously is

  • not obviously but let's say you're doing some slow processing on each element in the array.

  • I think I have that shown somewhere no, no, I don't.

  • Okay.

  • So let's say ‑‑ Ooops.

  • So I have a delay function which is just slow, it's just a slow thing.

  • So ... let's say processing Async and here processing Sync.

  • Okay, now, I'm going to turn on a thing I've literally hacked together this morning, which

  • is to simulate the repaint or the render in the browser, something I haven't touched on

  • is how all of this interacts with rendering ‑‑ I've kind of touched on it but not really

  • explained it.

  • So, basically the browser is kind of constrained by what you're doing javaScript, the browser

  • would like to repaint the screen every 16.6 milliseconds, 60 frame a second is ideal,

  • that's the fastest it will do repaints if it can.

  • But it's constrained by what you're doing in JavaScript for various reasons, so it can't

  • actually do a render if there is code on the stack, right.

  • Like the render kind of call is almost like a callback in itself.

  • It has to wait till the stack is clear.

  • The difference is that the render is given a higher priority than your callback, every

  • 16 milliseconds it's going to queue a rend, wait till the stack is clear before it can

  • actually do that render.

  • So this is ‑‑ this render queue is just simulating a render, every second it's can

  • I do a render?

  • Yes, can I do a render?

  • Yes.

  • Where, because our code isn't doing anything now.

  • If I run the code, you can see while we're doing this slow synchronous loop through the

  • array, our render is blocked, right, if our render is blocked you can't select text on

  • the screen, you can't click things and see the response, right, like the example I showed

  • earlier.

  • In this example, okay, it's blocked while we queue up the async time out, that relatively

  • quick but we're given ‑‑ we're kind of giving the render a chance between each element

  • because we've queued it up asynchronously to jump in there and do the render, does that

  • make sense?

  • >> Yeah >> Yeah, cool.

  • So, that's just kind of ‑‑ this is just like a simulation of how the rendering works,

  • but it just really shows you when people say don't block the event loop, this is exactly

  • what they're talking about.

  • They're saying don't put shitty slow code on the stack because when you do that the

  • browser can't do what it needs to do, create a nice fluid UI.

  • This is why when you're doing things like image processing or Animating too many things

  • gets sluggish if you're not careful about how you queue up that code.

  • So an example of that, we can see with the scroll handlers ‑‑ so scroll handle ‑‑

  • like scroll events in the DOM trigger a lot, right, they trigger like ‑‑ I presume

  • they trigger on every frame like every 16 milliseconds, if I have code like this this

  • right.

  • On document.scroll, animate something, or do some work.

  • If I have this code, like as I scroll it's going to queue up like a ton of callbacks

  • right.

  • And then it has to go through and process all of those and each of the processing of

  • those is slow, then, okay, you're not blocking the stack, you're flooding the queue with

  • queued events.

  • So, this is like just helping visualize, I guess, what happens when you actually trigger

  • all these callbacks, there's way you can debounce that to basically say okay, we're going to

  • queue up all those events, but let's do the slow work every few seconds or until the user

  • stops scrolling for some amount of time I think that's basically it.

  • There's a whole other talk in how the hell this works.

  • Because basically in running the code, like this code runs at Runtime, right, and it's

  • slowed down by I run it through a Esprima a JavaScript parser, I insert a big while

  • loop, that takes half a second, it just slow motions the code.

  • Ship it to web worker and do a whole bunch of stuff to visualize what's happening while

  • doing it at run time that makes sense.

  • A whole other talk in that.

  • I'm super excited about it and will talk to anyone about it after because I think it's

  • kind of neat, so with that, thanks very much ( applause)

>> (Phillip Roberts) hello, come in and sit down.

Subtitles and vocabulary

Click the word to look it up Click the word to find further inforamtion about it