Практика Shadowing: What the heck is the event loop anyway? | Philip Roberts | JSConf EU - Изучайте разговорный английский по видео

Создание урока...
1
Hello, everyone.
2
Thanks for coming to the side track.
3
It's awesome to see it packed out in here.
4
Can everyone give me a stretch?
5
That's good.
6
I need to stretch so I look less weird, okay.
7
So I want to talk about the event loop and what the heck is the event loop, as in the event loop inside JavaScript.
8
So first up, as he said, I work for and yet, which is an awesome little dev shop slash product company in the U .S.
9
Look us up if you need help with real -time stuff, that's what we're good at.
10
So, about 18 months ago, I'm a paid professional JavaScript developer.
11
I thought to myself, how does, like, JavaScript actually work?
12
And I wasn't entirely sure.
13
I'd heard V8 as a term, you know, Chrome's runtime, didn't really know what that meant, what that did.
14
I'd heard things like single -threaded, you know, obviously I'm using callbacks, how do callbacks work, so I kind of started a journey of,
15
like, reading and research and experimenting in the browser, which basically started like this,
16
right, I kind of was like, JavaScript, what are you?
17
And it's like, I'm a single -threader, non -blocking, asynchronous, concurrent language, all right, that's, yeah, cool,
18
I have a callback queue and some other APIs and stuff, right, I did not do a computer science degree.
19
I don't, I mean, these words, they're words.
20
So you know, I heard of, like, V8 and the various run times in the different browsers, so I, like, looked at V8 and said, do you have a call stack and event loop, a callback queue and some other APIs and stuff?
21
I have a call stack and a heap.
22
I don't know what those other things are.
23
Okay.
24
Interesting.
25
So basically 18 months pass.
26
Like we're 18 months later now, and, like, I think, I think I get this.
27
And so this is what I want to share with you today.
28
So 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 have used,
29
why callbacks are a thing which calls us hell but are required, and also if you're not, if you're an experienced JavaScript developer,
30
hopefully give you some kind of fresh insights into how the runtime
31
that you're using every day works so that you can kind of think about it a little better there.
32
So if we look at the JavaScript runtime itself, like V8, for example, which is the runtime inside Chrome,
33
this is what is, this is a simplified view, really, of what the JavaScript runtime is.
34
It's a heap, which is, we don't need to worry about that, it's kind of boring, it's just like where memory allocation happens.
35
And then there's the call stack, which is where your, like, stack frames are and all that kind of stuff stuff.
36
But if you, like, clone the V8 code base and grep for things like set timeout or DOM or XML HTTP request,
37
they're not in there.
38
They don't exist in V8.
39
Which is kind of a surprise to me, right?
40
Like, set timeout is one of those first things you use in JavaScript when you start thinking about async stuff, and it's not in the V8 source?
41
Hmm, interesting.
42
So, over this 18 months of discovery, I've come to realize that this is really the bigger picture
43
and this is what I'm hoping to get you all kind of on board with today and understand what these pieces are.
44
So we have the V8 runtime, but then we have these things called Web APIs, which are extra things that the browser provides, so the DOM, Ajax, set timeout, things like that.
45
Then we have this mythical event loop and the callback queue.
46
I'm sure you've heard some of these terms before, but maybe don't quite understand how these pieces like pull together.
47
So I'm going to start from the beginning.
48
Some of this will be new to, or, you know, the words might be new to people, other people might get this, but we're going to quickly kind of move on from here, so bear with me if this is obvious,
49
but I think for a lot of people it's not.
50
So JavaScript is a single -threaded programming language, single -threaded runtime, which means it has a single call stack, and it can do one thing at a time,
51
like that's what a single thread means is like the program can run one piece of code at a time.
52
So let's try and visualize that just to kind of get our heads around what that means.
53
So if I have some code like this on your left, we've got a few functions, a function multiply which multiplies two numbers,
54
square which calls multiply with the same number twice, a function which prints the square of a number by calling square and then calling console .log.
55
And then at the bottom of our file, we actually run print square.
56
Right?
57
This code all good?
58
Makes sense?
59
Cool.
60
So, if we run this, well...
61
I should back up a step, sorry.
62
So the call stack is basically a data structure which records basically where in the program we are.
63
So if we step into a function, we push something onto the stack.
64
If we return from a function, we pop off the top of the stack.
65
That's all the stack can do.
66
We push stuff on the top, pop off the top.
67
So if we run this file, well, there's kind of a main function, right, like the file itself.
68
So we push that onto the stack.
69
And we have some function definitions.
70
They're just like defining the state of the world.
71
And then finally we get to print square, right?
72
So print square is a function call, so we push that onto the stack, and immediately inside print square we're going to call square, which we're going to push onto the stack,
73
which calls multiply, and now we hit a return statement, right?
74
We multiply A and B and we return.
75
So I said when we return, we pop something off the stack.
76
So multiply off the stack, return into square, return into print square, console .log, print There's no return,
77
but it's implicit because we got to the end of the function, and we're done.
78
Right?
79
So that is like a visualization of the call stack.
80
Does that make sense?
81
Yes, Phil.
82
Okay.
83
Great.
84
So, even if you haven't really thought about or visualized the call stack before, you've undoubtedly come across it when you've been doing certainly browser side development.
85
So if we have code like this, a function baz, which calls bar, which calls foo, which throws an error, then if we run this in Chrome, we see something like this in the dev tools.
86
Right?
87
Unquote error oops.
88
And it prints the stack trace.
89
That is the stack trace, right?
90
The state of the stack when the error happened.
91
So unquote error oops, which was called in foo, which was called by bar, which was called by this anonymous function, which is our main, right?
92
Equally, if you've heard the term like blowing the stack, then this is an example of that, right?
93
Have a function foo which calls foo.
94
So what's going to happen?
95
Well, we run main, we call foo, which calls foo, which calls foo,
96
which calls foo, and ultimately Chrome says, well, hmm, you probably didn't mean to call foo 16 ,000 times recursively,
97
so I'll just, like, kill things for you and you can figure out where your bug lies, right?
98
So although I may be representing a new kind of side of the call stack, you've probably got some sense of it in your development practice already.
99
So the big question then comes is, like, what happens when things are slow?
100
So we talk about blocking and blocking behaviour and blocking, there's no strict definition of what is and isn't blocking.
101
Really it's just code that is slow, right?
102
So console .log is not very slow.
103
Doing a while loop from 1 to 10 billion is kind of slow.
104
Doing image processing is slow.
105
Network requests are slow.
106
So, things which are slow and on that stack are what a blocking means.
107
So here's a little example.
108
So let's say we have, this is like a fake bit of code, get synchronous, right?
109
Like jQuery's like Ajax request.
110
What would happen if those were synchronous requests?
111
So forget what we know about async callbacks, they're synchronous us.
112
So if we just go through it like we have been, we call get sync and then we wait.
113
Right?
114
Because we're doing network requests.
115
Networks relative to computers are very, very slow.
116
Hopefully that network request completes.
117
We can move on.
118
Wait.
119
Move on.
120
Wait.
121
And, I mean, this network request might never finish.
122
So, yeah, I guess I'll go home.
123
Finally, those three blocking behaviours complete and we can clear the stack.
124
So in a programming language which is single -threaded, you're not using threads like, say, Ruby, that's what happens, right?
125
We make a network request, we have to just wait until it's done because we have no way of handling that.
126
So why is this actually a problem?
127
The problem is because we are running code in browsers.
128
So, let's, why can't I, here we go, okay.
129
So this is just, this is Chrome.
130
This is the code I just ran.
131
Browsers don't give us, well, they do actually give us synchronous AJAX requests, but I'm actually just faking this out with a big while loop, because while loops are synchronous.
132
So I basically while looped for like a second or five seconds, I think, before continuing.
133
So, if I open up the console here, we can see what happens.
134
So we request foo .com, and, like, while this is happening, I can't do anything, right?
135
Even the run button hasn't finished re -rendering the fact that I previously clicked it, because the browser is blocked,
136
it's stuck, it can't do anything until those requests complete, and then all hell breaks loose, right, because I did some stuff, and it figured out that I had done it,
137
it just couldn't actually, like, render it, couldn't do anything.
138
And that's because...
139
if that call stack has things on it, and here it's got these, yeah, it's still going, we've got the asynchronous requests, we've blocked the call stack,
140
the browser can't do anything else, it can't render, it can't run any other code, it's stuck.
141
Not ideal, right?
142
If we want people to have nice fluid UIs, we can't block the stack.
143
So how do we handle this?
144
Well, the simplest solution we're provided with is asynchronous callbacks, right?
145
So there are almost no blocking functions in the browser, equally in node, they're all made asynchronous,
146
which basically means we run some code, give it a callback and we run that later, right?
147
If you've been writing JavaScript, you've seen asynchronous callbacks.
148
What does this actually look like?
149
So simple example to remind people just where we're at.
150
Code like this, console .log high, right?
151
We run the set timeout, but that queues the console .log for the future somehow, so then we skip straight on to jscontvu, log that, and then five seconds later, we log there.
152
Right?
153
Make sense?
154
Happy?
155
Basically like that set timeout is doing something.
156
So asynchronous callbacks with regards to the stack we saw before, how does this work?
157
So, let's run the code, console .log high, set timeout, okay, what's going to happen here?
158
We know that console .log there doesn't run immediately, it's going to run in five seconds time.
159
We can't push that console .log onto the stack, so somehow it just disappears.
160
We don't have, like, a way of describing this yet, but we'll come to it.
161
We log JSConf for you, clear, and then five seconds later somehow magically console .log that appears on the stack.
162
How does that happen?
163
And this is basically where the event loop comes in, and concurrency, right?
164
So I've been kind of partially lying to you and telling you that JavaScript can only do one thing at a time.
165
That is true.
166
JavaScript, the runtime, can only do one thing at a time.
167
It can't make an AJAX request while you're doing other code.
168
It can't do a set time up while you're doing other code.
169
The reason we can do things concurrently is that the browser is more than just the runtime. So remember this diagram.
170
The JavaScript runtime can do one thing at a time, but the browser gives us these other things, right?
171
It gives us these web APIs.
172
These are effectively threads that you can't access like threads, you can just, like, make calls to, and those pieces of the browser are where this concurrency kicks in.
173
If you're a back -end person, this diagram looks basically identical for Node, except instead of web APIs, we have C++ APIs, right,
174
and the threading and all that stuff is hidden from you by being run in, like, C++ land.
175
Okay.
176
So now that we have this picture, let's see how this code runs in this kind of more full picture of what a browser looks like.
177
So, same as before, run the code, console log high, log high to the console, simple.
178
Now we can see what happens when we call set timeout.
179
So when we call set timeout, we pass this callback function and a delay to the set timeout call.
180
Now set timeout is an API provided to us by the browser, remember I said it doesn't live like in the V8 source, it's like extra stuff we get in the environment that we're running the JavaScript runtime in.
181
So, effectively, we kick off a timer, right, and the browser kicks off a timer for you.
182
And now it's going to handle the countdown for you, right?
183
So that means that our set timeout call itself is now complete, so we can pop off the stack.
184
JSConf for you, clear.
185
So now we've got this timer in the web API, which five seconds later is going to complete.
186
Now, the web API can't just, like, start modifying your code, right?
187
It can't just, like, chuck stuff onto the stack when it's ready, because if it did, it would, like, just appear randomly in the middle of your code.
188
So this is where the task queue or the callback queue kicks in.
189
So basically any of the web APIs, when they're done, they push your callback onto the task queue.
190
And finally we get to the event loop.
191
The title of the talk is what the heck is the event loop.
192
The event loop is the simplest little piece in this whole equation, and it has one very simple job.
193
The event loop's job is to look at the stack and look at the task queue.
194
If the stack is empty, it takes the first thing on the queue and pushes onto the stack, which effectively runs it, right?
195
So here we can see that now the stack is clear, there's a callback on the task queue, so the event loop runs.
196
It says, oh, I get to do something.
197
Here.
198
Pushes the callback back onto the stack.
199
The stack is like JavaScript land, this is back inside V8.
200
So the callback appears on the stack and gets run, console .log there, and we're done. Does that make sense?
201
Everyone with me?
202
Awesome.
203
Okay.
204
So now we can see how this works with probably one of the first encounters you would have had with async stuff, which is when for some weird reason someone says,
205
oh, you have to call set timeout zero like okay, you want me to run the function in zero time, why would I wrap it in a set timeout?
206
The first time you come across this, if you're anything like me, you're like, okay, I sort of see it's doing something, but I don't really know why.
207
And the reason is, generally, if you're trying to defer something until the stack is clear.
208
So we know looking at this, if you've written JavaScript, we're going to see the same result.
209
We're going to see high, we're going to see JSConf for you, and there's going to somehow appear at the end.
210
So running it, we can see how that happens.
211
Console .log high.
212
Set time at zero.
213
That's going to complete immediately and push the call back onto the queue.
214
But remember what I said about the event loop.
215
It has to wait until the stack is clear before it can push the call back onto the stack.
216
So your stack is going to continue to run, right?
217
Your main file is going to continue to run, console .log .js comp for you and clear.
218
Now that we're clear, the event loop can kick in on your call back.
219
So that's like an example of set time at zero is like pushing, deferring that execution of code for whatever reason to the end of the stack.
220
Or until the stack is clear.
221
Okay.
222
So all these web APIs work the same way, right?
223
If we have AJAX requests, we make an AJAX request to a URL with a callback, just works the same way.
224
The code for running that request does not live in the JavaScript runtime, it lives in the browser as a web API, so we spin up a XHR web API with a callback and the URL,
225
your code can continue to run until the XHR request completes.
226
Or doesn't complete.
227
It may never complete, but that's okay.
228
Your stack can continue to run.
229
Assuming it does complete, callback gets pushed onto the queue, picked up by the event loop, loop, and it's run.
230
Right?
231
That's all that happens when an async call happens.
232
Okay.
233
So let's do a crazy complicated example.
234
So I hope this is going to work.
235
If you hadn't kind of realized, like, this is all in keynote, there's, like, I don't know how, like, 500 animation steps in this whole deck, so hopefully that, oh, huh,
236
oh, so,
237
interesting, we were We're given a link. Is this big enough?
238
Can people see?
239
Okay.
240
So, basically, I wrote this talk for Skelton .js earlier in the year, and I did it there.
241
And then after the talk, I broke half of the slides
242
and could not be bothered to redo all the slides
243
because it was a total pain in the ass in keynote to do it.
244
So, instead, I took the much easier route of writing a tool which can visualize the JavaScript runtime at runtime. And it's called loop.
245
So let's just run this example, which was kind of the example we had on the previous slide.
246
I haven't shimmed XHR yet.
247
It's doable.
248
I just haven't done it.
249
So, as you can see, the code, we're going to log something thing.
250
This is a simple shim around document .advent listener.
251
Set timeout and we're going to do a console .log.
252
So I'm just going to run it and see what happens.
253
So add a DOM API, add a timeout, timeout is going to count down, code is going to continue to run, pushes the callback into the queue which runs,
254
which runs the console .log, and we're done.
255
If I click on here, then it's going to trigger the web API, cue the callback for the click and run it.
256
If I click 100 times, we can see what happens, right?
257
I clicked.
258
The click doesn't get processed immediately.
259
The click gets pushed onto the queue, and as the queue gets processed, eventually my click is going to get dealt with, right?
260
Right?
261
So I have a few more examples I want to run through here, except I don't know how to see tabs,
262
so let's just see if I can find it, there we go, okay.
263
So I'm just going to run through a few examples just to kind of talk about a few things
264
that you might have run into and not kind of thought about with async APIs.
265
So, in this example, we call set timeout four times with a one -second delay and run console .log high.
266
So, if we run it, we can see that we run a few timeouts, but the timeout callbacks get queued.
267
Right?
268
So, that fourth callback, we asked for a one -second delay, and it's still waiting.
269
The callback hasn't run, right?
270
So this kind of illustrates the, like, what set timeout is actually doing.
271
Set timeout is not a guaranteed time to execution, it's a minimum time to execution.
272
Just like set timeout zero doesn't run the code immediately, it runs the code next -ish sometime.
273
Right?
274
So, in this example, I want to talk about callbacks.
275
So, depending on who you speak to and how they phrase things, callbacks can be one of two things.
276
Callbacks can be any function that another function calls, or callbacks can be more explicitly an asynchronous callback,
277
as in one that is going to get pushed on to the callback queue at some point in the future.
278
So this little bit of code illustrates the difference, right?
279
Right?
280
The for each 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.
281
It's running it within the current stack.
282
We could define an asynchronous for each, so we could, it's going to take an array and a callback, and then for each item in the array,
283
it's going to do a set timeout zero with that callback.
284
Right?
285
I guess this should actually pass in the value, but anyway.
286
So I'm going to run it and we can see what the difference is.
287
So for the first block of code that runs, it's going to sit and block the stack, right?
288
Until it's complete.
289
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,
290
and then we can actually run through and do the console .logs.
291
So, in this example, the console .log is fast, so the benefit of doing it asynchronously isn't obvious,
292
but let's say you're doing some slow processing on each element in the array.
293
I think I have that shown somewhere, no, no, I don't, okay.
294
So let's say, oops, so I have a delay function which is just slow, right, it's just a slow thing.
295
So let's say processing async,
296
and here, processing sync, okay.
297
Now I'm going to turn on a thing I've just been literally hacked together this morning, which is to simulate the repaint or the render in the browser.
298
So something I haven't touched on is how all of this interacts with rendering.
299
I kind of touched on it, but, yeah, not really explained it.
300
So basically the browser is kind of constrained by what you're doing in JavaScript, right?
301
The browser would like to repaint the screen every 16 .6 milliseconds, 60 frames a second, is our ideal, like, that's as fast as it will do repaints if it possibly can.
302
But it's constrained by what you're doing in JavaScript for various reasons.
303
So it can't actually do a render if there is code on the stack, right?
304
It's like the render kind of call is almost like a callback itself, right?
305
It has to wait until the stack is clear.
306
Now the difference is that the render is given a higher priority than your callbacks.
307
So basically every 16 milliseconds it's going to queue a render
308
and then it's going to have to wait until the stack is clear before it can actually do that render.
309
So this is, this render queue is just simulating a render, right?
310
So every second it's like, can I do a render, yes.
311
Can I do a render, yes because our code isn't doing anything now.
312
However, if I run the code, we can see that while we're doing this slow, synchronous loop through this array, our render is blocked, right?
313
And if our render is blocked, you can't select text on the screen.
314
You can't click things and see the response, right?
315
Like that example I showed earlier.
316
In this example, okay, it's blocked while we queue up the async timeouts, but that's relatively quick. But we're given,
317
we're kind of giving the render a chance between each element
318
because we've queued it up asynchronously to kind of jump in there and do the render.
319
Did that make sense?
320
Yeah.
321
Cool.
322
So, yeah, that's just kind of, this is just like a simulation, right, of how the rendering works.
323
But it just really shows you, like, when people say don't block the event loop, this is exactly what they're talking about.
324
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, which is like create a nice fluid UI, right?
325
This is why doing things like image processing or whatever, or like animating too many things just gets kind of sluggish, right, if you're not careful about how you queue up that code.
326
So an example of that we can see with scroll handlers this.
327
So scroll events in the DOM trigger a lot, right?
328
They trigger like every, I presume they trigger on every frame, so every 16 milliseconds.
329
So if I have code like this, right, on document .scroll People animate something or do some work.
330
If I have this code, as I scroll, it's going to queue up a ton of callbacks, right?
331
And then it has to go through and process all of those.
332
And if each of the processing of those is slow, then okay, you're not blocking the stack, but you're kind of flooding the queue with events, right?
333
So this is just helping visualize, I guess, what happens when you actually trigger all these callbacks.
334
So, there's ways you can debounce that to basically say, okay, we're going to queue up all those events,
335
but let's only do the slow work every few seconds or until the user stops scrolling for some amount of time.
336
Cool.
337
So I think that's basically it.
338
There's like a whole other talk in how the hell this works.
339
Because, basically, in running the code, like, this code runs at runtime, right?
340
And it's slowed down by I run it through a Spreema, which is a JavaScript parser.
341
Before and after every single statement in the code, I insert a big while loop that takes half a second.
342
So basically just, like, slow motions the code.
343
Ship it to a web worker and then do a whole bunch of stuff to, like, visualize what's happening while doing it at runtime, if that makes sense.
344
So there's like a whole other talk in all of that, but I'm super excited about it and super happy to talk to anyone after about it, because I think it's kind of neat.
345
So with that, thanks very much.

Цели разговорной практики в этом видео

Это видео поможет вам улучшить навык понимания и воспроизведения разговорного английского в контексте технической темы. Цель — освоить естественную речь с паузами, эмоциональной окраской и быстрым темпом, typical для профессиональных презентаций. Это отличная возможность для практики разговорного английского с использованием реального контента, а не учебных текстов.

Банк фраз для повторения

  • "What the heck is..." — разговорное выражение для выражения удивления или непонимания.
  • "Can everyone give me a stretch" — приглашение к действию в неформальной обстановке.
  • "I wasn't entirely sure" — честное признание неполного знания.
  • "That's what we're good at" — упоминание сильных сторон.
  • "How does... actually work?" — вопрос, который часто используется в технических обсуждениях.

Эти фразы можно использовать в повседневной речи и рабочих диалогах, поэтому их повторение через shadowing (теньевую практику) поможет закрепить их в активном словарном западе.

Исправляем слабые места в произношении иритме

В видео много быстрых переходов между словами, сокращений (например, "I'm", "don't") и пауз, которые важны для естественной речи. Наибольшую сложность может представить правильно произносить технические термины: "event loop", "call stack", "heap". Используйте это видео как shadowing site для тренировки ритма — повторяйте за спикером, копируя его интонацию и темп. Обратите внимание на ударения в словах like "concurrent" или "asynchronous" — это поможет улучшить произношение английского и сделать речь более понятной.

Пractise regularly, и вы заметите, как ваша речь становится более уверенной и естественной, даже в сложных темах!

Грамматика в этом видео

Конструкции, которые говорящий использует чаще всего, с точными словами из видео:

КонструкцияВ видео
Present Perfect Continuous have/has been + -ing — действие началось раньше и продолжаетсяyou've been doing · you've been writing
Present Perfect have/has + причастие прошедшего времени — прошлое действие, важное сейчасI've come · you've heard · haven't really thought
Придаточные определительные who / which + предложение — уточнение о человеке или предметеyet, which is · example, which is · heap, which is
Пассивный залог be + причастие прошедшего времени — важно, что происходит, а не кто это делаетare required · was called · is blocked

Что такое техника Shadowing?

Shadowing — это научно обоснованная техника изучения языка, изначально разработанная для подготовки профессиональных переводчиков и популяризированная полиглотом доктором Александром Аргуэльесом. Метод прост, но эффективен: вы слушаете аудио на английском от носителей языка и немедленно повторяете вслух — как тень, следующая за говорящим с задержкой в 1–2 секунды. В отличие от пассивного прослушивания или грамматических упражнений, Shadowing заставляет мозг и мышцы рта одновременно обрабатывать и воспроизводить реальные речевые паттерны. Исследования показывают, что это значительно улучшает точность произношения, интонацию, ритм, связную речь, понимание на слух и беглость речи — что делает его одним из самых эффективных методов для подготовки к IELTS Speaking и реального общения на английском.

Техника шедоуинга: читать полное пошаговое руководство →