Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:01,150 --> 00:00:02,580
Welcome back. | www.downloadly.ir
2
00:00:02,580 --> 00:00:05,000
Let's now learn all about the event loop,
3
00:00:05,000 --> 00:00:08,150
which is the heart of the Node.js architecture.
4
00:00:08,150 --> 00:00:10,580
And this is probably the most important lecture
5
00:00:10,580 --> 00:00:13,500
in this section, so make sure you really understand
6
00:00:13,500 --> 00:00:16,510
everything that I show you during this video.
7
00:00:16,510 --> 00:00:17,813
So, let's get started.
8
00:00:18,800 --> 00:00:21,880
So, here is a diagram similar to the last lecture
9
00:00:21,880 --> 00:00:25,170
so that we know exactly what we're talking about here.
10
00:00:25,170 --> 00:00:28,240
So, we're still in a Node process in the single thread
11
00:00:28,240 --> 00:00:30,810
where the event loop runs, all right?
12
00:00:30,810 --> 00:00:32,530
Now, the first thing that you need
13
00:00:32,530 --> 00:00:34,750
to know is that the event loop is
14
00:00:34,750 --> 00:00:36,350
where all the application code
15
00:00:36,350 --> 00:00:39,550
that is inside callback functions is executed.
16
00:00:39,550 --> 00:00:43,640
So, basically, all code that is not top level code will run
17
00:00:43,640 --> 00:00:45,250
in the event loop.
18
00:00:45,250 --> 00:00:48,450
Some parts might get offloaded to the thread pool
19
00:00:48,450 --> 00:00:50,140
as we saw in the last lecture,
20
00:00:50,140 --> 00:00:53,430
but it's the event loop that takes care of all this.
21
00:00:53,430 --> 00:00:56,370
As I said before, it really is the heart
22
00:00:56,370 --> 00:00:58,360
of the Node architecture.
23
00:00:58,360 --> 00:01:01,660
Okay, now, as I mentioned many times in the first part
24
00:01:01,660 --> 00:01:04,300
of the course, Node.js is all built
25
00:01:04,300 --> 00:01:05,860
around callback functions.
26
00:01:05,860 --> 00:01:08,160
So, functions that are called as soon
27
00:01:08,160 --> 00:01:11,700
as some work is finished some time in the future.
28
00:01:11,700 --> 00:01:12,960
Remember that?
29
00:01:12,960 --> 00:01:15,310
And it works this way because Node
30
00:01:15,310 --> 00:01:17,750
uses an event-triggered architecture,
31
00:01:17,750 --> 00:01:20,480
which is something that we're gonna talk about in one
32
00:01:20,480 --> 00:01:22,100
of the next videos.
33
00:01:22,100 --> 00:01:24,180
But what you need to know for now is
34
00:01:24,180 --> 00:01:26,020
that things like our application
35
00:01:26,020 --> 00:01:31,020
receiving an HTTP request on our server or a timer expiring
36
00:01:31,130 --> 00:01:34,860
or a file finishing to read, all these will emit events
37
00:01:34,860 --> 00:01:37,350
as soon as they are done with their work,
38
00:01:37,350 --> 00:01:40,150
and our event loop will then pick up these events
39
00:01:40,150 --> 00:01:41,880
and call the callback functions
40
00:01:41,880 --> 00:01:44,750
that are associated with each event.
41
00:01:44,750 --> 00:01:46,520
Okay, make sense?
42
00:01:46,520 --> 00:01:49,680
So, again, the event loop receives events
43
00:01:49,680 --> 00:01:51,800
each time something important happens,
44
00:01:51,800 --> 00:01:54,440
and will then call the necessary callbacks
45
00:01:54,440 --> 00:01:56,443
such as we define in our code.
46
00:01:57,300 --> 00:01:59,690
So, in summary, it's usually said
47
00:01:59,690 --> 00:02:02,600
that the event loop does the orchestration,
48
00:02:02,600 --> 00:02:05,310
which simply means that it receives events,
49
00:02:05,310 --> 00:02:07,330
calls their callback functions,
50
00:02:07,330 --> 00:02:11,290
and offloads the more expensive tasks to the thread pool.
51
00:02:11,290 --> 00:02:14,670
Now, how does all this actually work behind the scenes?
52
00:02:14,670 --> 00:02:17,960
In what order are these callbacks executed?
53
00:02:17,960 --> 00:02:20,543
Well, that is what we're gonna find out next.
54
00:02:21,460 --> 00:02:24,630
So, remember, when we start our Node application,
55
00:02:24,630 --> 00:02:27,430
the event loop starts running right away.
56
00:02:27,430 --> 00:02:29,720
Now, the event loop has multiple phases,
57
00:02:29,720 --> 00:02:32,330
and each phase has a callback queue,
58
00:02:32,330 --> 00:02:35,060
which are the callbacks coming from the events
59
00:02:35,060 --> 00:02:36,690
that the event loop receives,
60
00:02:36,690 --> 00:02:39,830
just as we talked about in the last slide.
61
00:02:39,830 --> 00:02:41,830
Now, in some places you will read
62
00:02:41,830 --> 00:02:45,520
that there is only one callback queue or one event queue,
63
00:02:45,520 --> 00:02:49,290
but in fact, as I said, the event loop has many phases
64
00:02:49,290 --> 00:02:52,290
where each phase has its own callback queue.
65
00:02:52,290 --> 00:02:56,090
So, let's now take a look at the four most important phases.
66
00:02:56,090 --> 00:02:58,090
There are one or two other phases
67
00:02:58,090 --> 00:02:59,890
that are used internally by Node,
68
00:02:59,890 --> 00:03:01,360
but these are not that important
69
00:03:01,360 --> 00:03:03,530
and I'm not gonna talk about them.
70
00:03:03,530 --> 00:03:05,230
So, the first phase takes care
71
00:03:05,230 --> 00:03:07,860
of callbacks of expired timers,
72
00:03:07,860 --> 00:03:10,880
for example, from the setTimeout() function.
73
00:03:10,880 --> 00:03:13,210
So, if there are callback functions from timers
74
00:03:13,210 --> 00:03:15,750
that just expired, these are the first ones
75
00:03:15,750 --> 00:03:18,010
to be processed by the event loop.
76
00:03:18,010 --> 00:03:21,040
If a timer expires later during the time when one
77
00:03:21,040 --> 00:03:23,370
of the other phases are being processed,
78
00:03:23,370 --> 00:03:26,860
well, then the callback of that timer will only be called
79
00:03:26,860 --> 00:03:30,450
as soon as the event loop comes back to this first phase.
80
00:03:30,450 --> 00:03:31,580
Make sense?
81
00:03:31,580 --> 00:03:34,520
And it works like this in all four phases.
82
00:03:34,520 --> 00:03:37,250
So, callbacks in each queue are processed one
83
00:03:37,250 --> 00:03:40,810
by one until there are no ones left in the queue,
84
00:03:40,810 --> 00:03:44,630
and only then, the event loop will enter the next phase.
85
00:03:44,630 --> 00:03:49,180
Next up, we have I/O polling and execution of I/O callbacks.
86
00:03:49,180 --> 00:03:52,840
And again, remember that I/O stands for input/output.
87
00:03:52,840 --> 00:03:56,040
So, polling basically means looking for new I/O events
88
00:03:56,040 --> 00:03:58,060
that are ready to be processed
89
00:03:58,060 --> 00:04:00,890
and putting them into the callback queue.
90
00:04:00,890 --> 00:04:04,110
And remember that in the context of a Node application,
91
00:04:04,110 --> 00:04:08,710
I/O means mainly stuff like networking and file access,
92
00:04:08,710 --> 00:04:12,150
and so, it's in this phase where probably 99%
93
00:04:12,150 --> 00:04:14,270
of our code gets executed,
94
00:04:14,270 --> 00:04:16,640
simply because in a typical Node app,
95
00:04:16,640 --> 00:04:20,500
the bulk of what we need to do is related to networking
96
00:04:20,500 --> 00:04:23,170
and also, file accessing.
97
00:04:23,170 --> 00:04:26,490
The next phase is for setImmediate callbacks,
98
00:04:26,490 --> 00:04:29,250
and setImmediate is a special kind of timer
99
00:04:29,250 --> 00:04:32,810
that we can use if we want to process callbacks immediately
100
00:04:32,810 --> 00:04:36,130
after the I/O polling and execution phase,
101
00:04:36,130 --> 00:04:39,173
which can be important in some more advanced use cases.
102
00:04:40,110 --> 00:04:40,943
All right.
103
00:04:40,943 --> 00:04:44,940
And finally, the fourth phase is for close callbacks,
104
00:04:44,940 --> 00:04:47,530
which are, again, not that important for us,
105
00:04:47,530 --> 00:04:50,820
but I put this here anyway for the sake of completeness.
106
00:04:50,820 --> 00:04:54,450
Basically, in this phase, all close events are processed,
107
00:04:54,450 --> 00:04:58,920
for example, for when a web server or a WebSocket shut down.
108
00:04:58,920 --> 00:05:01,920
So, these are the four phases in the event loop,
109
00:05:01,920 --> 00:05:05,400
but besides these four callback queues that we just saw,
110
00:05:05,400 --> 00:05:08,330
there are actually also two other queues,
111
00:05:08,330 --> 00:05:11,600
the nextTick() queue and the other microtasks queue,
112
00:05:11,600 --> 00:05:14,780
which is mainly for resolved promises.
113
00:05:14,780 --> 00:05:16,890
If you're not familiar with promises,
114
00:05:16,890 --> 00:05:20,240
we will talk about them a bit in a later section.
115
00:05:20,240 --> 00:05:22,620
Anyway, if there are any callbacks in one
116
00:05:22,620 --> 00:05:24,750
of these two queues to be processed,
117
00:05:24,750 --> 00:05:27,840
they will be executed right after the current phase
118
00:05:27,840 --> 00:05:30,250
of the event loop finishes instead of waiting
119
00:05:30,250 --> 00:05:32,380
for the entire loop to finish.
120
00:05:32,380 --> 00:05:33,370
Okay?
121
00:05:33,370 --> 00:05:36,680
So, in other words, after each of these four phases,
122
00:05:36,680 --> 00:05:40,340
if there are any callbacks in these two special queues,
123
00:05:40,340 --> 00:05:42,880
they will be executed right away.
124
00:05:42,880 --> 00:05:46,030
Now, for example, imagine that a promise resolves
125
00:05:46,030 --> 00:05:49,730
and returns some data from an API call while the callback
126
00:05:49,730 --> 00:05:52,690
of an expired timer is running.
127
00:05:52,690 --> 00:05:56,050
So, in this case, the promise callback will be executed
128
00:05:56,050 --> 00:05:59,230
right after the one from the timer finishes.
129
00:05:59,230 --> 00:06:00,490
Okay?
130
00:06:00,490 --> 00:06:03,480
And the same logic also applies to the nextTick() queue,
131
00:06:03,480 --> 00:06:05,290
which we didn't talk about yet.
132
00:06:05,290 --> 00:06:09,060
So, basically, process the nextTick() is a function
133
00:06:09,060 --> 00:06:11,610
that we can use when we really, really need
134
00:06:11,610 --> 00:06:13,740
to execute a certain callback
135
00:06:13,740 --> 00:06:16,290
right after the current event loop phase.
136
00:06:16,290 --> 00:06:18,810
It's a bit similar to setImmediate,
137
00:06:18,810 --> 00:06:21,540
with the difference that setImmediate only runs
138
00:06:21,540 --> 00:06:23,400
after the I/O callback phase.
139
00:06:23,400 --> 00:06:24,600
What is similar, though,
140
00:06:24,600 --> 00:06:27,930
is that both are for really advanced use cases,
141
00:06:27,930 --> 00:06:30,080
and we're probably not even gonna need them
142
00:06:30,080 --> 00:06:31,580
throughout this course.
143
00:06:31,580 --> 00:06:34,660
But anyway, I wanted to include this more complex stuff here
144
00:06:34,660 --> 00:06:36,700
as well so that you have the tools
145
00:06:36,700 --> 00:06:38,940
that you need if you really need
146
00:06:38,940 --> 00:06:42,980
to dig deep into Node.js if you want to.
147
00:06:42,980 --> 00:06:46,210
All right, and with that, we actually finished one tick
148
00:06:46,210 --> 00:06:50,360
of the event loop, and a tick is basically just one cycle
149
00:06:50,360 --> 00:06:51,580
in this loop.
150
00:06:51,580 --> 00:06:54,840
So, now it's time to decide whether the loop should continue
151
00:06:54,840 --> 00:06:58,520
to the next tick or if the program should exit.
152
00:06:58,520 --> 00:07:00,720
And how does Node do that?
153
00:07:00,720 --> 00:07:02,310
Well, it's very simple.
154
00:07:02,310 --> 00:07:05,100
Node simply checks whether there are any timers
155
00:07:05,100 --> 00:07:08,440
or I/O tasks that are still running in the background,
156
00:07:08,440 --> 00:07:12,180
and if there aren't any, then it will exit the application.
157
00:07:12,180 --> 00:07:15,430
But if there are any pending timers or I/O tasks,
158
00:07:15,430 --> 00:07:17,870
well, then it will continue running the event loop
159
00:07:17,870 --> 00:07:20,500
and go straight to the next tick.
160
00:07:20,500 --> 00:07:22,030
So, for example, when we're listening
161
00:07:22,030 --> 00:07:24,740
for incoming HTTP requests like we did
162
00:07:24,740 --> 00:07:27,770
in our Node farm project in a previous section,
163
00:07:27,770 --> 00:07:30,600
we were basically running an I/O task,
164
00:07:30,600 --> 00:07:32,320
and that is why the event loop,
165
00:07:32,320 --> 00:07:34,640
and therefore, Node.js, keep running
166
00:07:34,640 --> 00:07:38,600
and keep listening for new HTTP requests coming in
167
00:07:38,600 --> 00:07:41,920
instead of just exiting the application.
168
00:07:41,920 --> 00:07:44,450
Also, when we're writing or reading a file
169
00:07:44,450 --> 00:07:47,480
in the background, that's also an I/O task,
170
00:07:47,480 --> 00:07:50,210
and so, it makes sense that the app doesn't exit
171
00:07:50,210 --> 00:07:53,260
while it's working with that file, right?
172
00:07:53,260 --> 00:07:55,780
Okay, and this is basically what you should know
173
00:07:55,780 --> 00:07:57,930
about the Node.js event loop.
174
00:07:57,930 --> 00:08:00,260
If you need even more detail than this,
175
00:08:00,260 --> 00:08:01,760
well, you can always try to read
176
00:08:01,760 --> 00:08:04,860
the official Node documentation, which should be quite easy
177
00:08:04,860 --> 00:08:07,060
for you to understand at this point now
178
00:08:07,060 --> 00:08:10,570
that you already understand most of the event loop anyway.
179
00:08:10,570 --> 00:08:12,830
And I just wanna emphasize that it's really,
180
00:08:12,830 --> 00:08:15,940
really important for you to correctly understand
181
00:08:15,940 --> 00:08:18,280
the event loop so that you can write your own
182
00:08:18,280 --> 00:08:21,390
performing code and also debug your own code
183
00:08:21,390 --> 00:08:24,173
when something goes wrong in an unexpected way.
184
00:08:25,720 --> 00:08:27,770
And now, just to finish, let's review some
185
00:08:27,770 --> 00:08:29,810
of the stuff we talked about here.
186
00:08:29,810 --> 00:08:32,490
So, in a nutshell, the most important thing
187
00:08:32,490 --> 00:08:34,620
that I want you to understand from this lecture,
188
00:08:34,620 --> 00:08:36,740
and maybe from this entire course,
189
00:08:36,740 --> 00:08:38,559
is that event loop is what makes
190
00:08:38,559 --> 00:08:41,630
asynchronous programming possible in Node.js,
191
00:08:41,630 --> 00:08:45,190
making it the most important feature in Node's design
192
00:08:45,190 --> 00:08:47,580
and making Node.js completely different
193
00:08:47,580 --> 00:08:49,050
from other platforms.
194
00:08:49,050 --> 00:08:51,600
It takes care of all incoming events
195
00:08:51,600 --> 00:08:55,120
and performs orchestration by offloading heavier tasks
196
00:08:55,120 --> 00:08:58,840
into the thread pool, and doing the most simple work itself.
197
00:08:58,840 --> 00:09:01,520
Also, remember that we need the event loop
198
00:09:01,520 --> 00:09:05,260
because in Node.js everything works in one single thread,
199
00:09:05,260 --> 00:09:07,260
and so, you can have thousands or millions
200
00:09:07,260 --> 00:09:11,230
of users accessing the same thread at the same time.
201
00:09:11,230 --> 00:09:13,690
This makes Node so lightweight and scalable,
202
00:09:13,690 --> 00:09:16,290
but at the same time, it comes with the danger
203
00:09:16,290 --> 00:09:17,930
of blocking our single thread,
204
00:09:17,930 --> 00:09:20,140
which would make the entire app slow
205
00:09:20,140 --> 00:09:25,140
or even stop for all your users accessing the app, right?
206
00:09:25,340 --> 00:09:28,110
Now, in other languages like PHP running on
207
00:09:28,110 --> 00:09:31,300
an Apache server, basically, a new thread is created
208
00:09:31,300 --> 00:09:35,200
for each new user, which is way more resource-intensive.
209
00:09:35,200 --> 00:09:37,180
But on the other hand, there is no danger
210
00:09:37,180 --> 00:09:39,160
of blocking, right?
211
00:09:39,160 --> 00:09:41,430
So, that whole model makes it a bit easier
212
00:09:41,430 --> 00:09:44,340
to use PHP for beginners, but of course,
213
00:09:44,340 --> 00:09:46,540
it comes with its own disadvantages,
214
00:09:46,540 --> 00:09:48,890
which I'm not gonna go into at this point.
215
00:09:48,890 --> 00:09:50,690
Anyway, let me again remind you
216
00:09:50,690 --> 00:09:54,860
that it's your responsibility to not block the event loop,
217
00:09:54,860 --> 00:09:58,150
and so here's a couple of guidelines for that.
218
00:09:58,150 --> 00:10:00,490
First off, don't use the sync versions
219
00:10:00,490 --> 00:10:02,850
of functions in the fs, crypto,
220
00:10:02,850 --> 00:10:06,450
or zlib modules in your callback functions, okay?
221
00:10:06,450 --> 00:10:09,210
So, in our first project, we actually did use
222
00:10:09,210 --> 00:10:12,610
the synchronous version, but it was in the top level code,
223
00:10:12,610 --> 00:10:15,000
so outside of any callback.
224
00:10:15,000 --> 00:10:18,520
And since that code runs before the event loop even starts,
225
00:10:18,520 --> 00:10:22,200
well, it's not problem to use the synchronous version there.
226
00:10:22,200 --> 00:10:24,910
Also, and this is probably pretty obviously,
227
00:10:24,910 --> 00:10:28,140
don't perform very complex calculations in the event loop.
228
00:10:28,140 --> 00:10:29,730
So, stuff like crunching millions
229
00:10:29,730 --> 00:10:33,890
of numbers in loops inside of loops, or something like that.
230
00:10:33,890 --> 00:10:37,550
Next, be careful with JSON in very large objects
231
00:10:37,550 --> 00:10:40,480
because at some point, it can start to take a long time
232
00:10:40,480 --> 00:10:43,440
to parse, or to stringify, JSON.
233
00:10:43,440 --> 00:10:47,170
And finally, don't use all too complex regular expressions,
234
00:10:47,170 --> 00:10:49,840
for example, with multiple nested quantifiers
235
00:10:49,840 --> 00:10:52,130
or back references, because again,
236
00:10:52,130 --> 00:10:54,810
they can take longer than expected.
237
00:10:54,810 --> 00:10:56,680
These are, of course, just a couple
238
00:10:56,680 --> 00:10:59,700
of high level guidelines, but they will get you started
239
00:10:59,700 --> 00:11:00,803
on the right path.
240
00:11:01,650 --> 00:11:03,490
Now, there are some potential solutions
241
00:11:03,490 --> 00:11:06,390
to these blocking problems, like manually offloading
242
00:11:06,390 --> 00:11:09,750
to the thread pool or using child processes,
243
00:11:09,750 --> 00:11:12,070
and we might talk about this by the end of the course
244
00:11:12,070 --> 00:11:14,370
or some time in the future, but for now,
245
00:11:14,370 --> 00:11:17,460
it's important that you understand and follow this advice
246
00:11:17,460 --> 00:11:20,110
of really not blocking the event loop.
247
00:11:20,110 --> 00:11:21,600
All right.
248
00:11:21,600 --> 00:11:24,520
Next up, I'm gonna give you a small example
249
00:11:24,520 --> 00:11:25,990
to show you some of the stuff
250
00:11:25,990 --> 00:11:27,640
that we talked about in practice. | www.downloadly.ir
20421
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.