﻿1
00:00:01,150 --> 00:00:02,580
‫Welcome back.

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,560
‫is that event loop is what makes

190
00:08:38,560 --> 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.

