|
1 | 1 |
|
2 | 2 | **What is the Event Loop (in Node.js)?** |
3 | 3 |
|
4 | | -Node.js is a single-threaded JavaScript runtime. To handle asynchronous operations efficiently without blocking the single thread, it uses an event loop. |
| 4 | +Node.js is a single-threaded JavaScript runtime. The event loop allows Node.js to perform non-blocking I/O operations by offloading operations to the system kernel whenever possible.Modern kernels are multi-threaded and handle multiple operations executing in the background. When one of these operations completes, the kernel sends appropriate callback to the poll queue. |
5 | 5 |
|
6 | 6 | **Key Concepts from the Node.js Website:** |
7 | 7 | 1. **Single Thread:** Node.js runs on a single thread. This means only one piece of code can be executed at a time. |
8 | 8 | 2. **Non-Blocking I/O:** Node.js uses asynchronous I/O operations. When an I/O operation is started, a callback function is registered, and the program continues. When the I/O completes, the callback is executed. |
9 | 9 | 3. **Event Loop:** The event loop continuously monitors the call stack and the callback queue. When the call stack is empty, the event loop takes the first callback from the queue and puts it onto the call stack for execution. |
10 | 10 |
|
11 | 11 | **Phases of the Event Loop (Detailed):** |
12 | | - |
13 | | -Node.js Event Loop order: |
14 | | - The Node.js event loop generally follows this order (simplified): |
15 | 12 | 1. **Timers Phase:** `setTimeout()` and `setInterval()` callbacks with expired timers executed. |
16 | 13 | 2. **Pending I/O Callbacks Phase:** Callbacks from some system operations. Eg: TCP Errors(ECONNREFUSED) |
17 | 14 | 3. **Idle, Prepare Phase:** Internal Node.js usage for housekeeping. |
@@ -128,3 +125,81 @@ File content: Hello, this is a test file. |
128 | 125 | * The event loop allows Node.js to handle many asynchronous operations concurrently on a single thread. |
129 | 126 | * The phases of the event loop define the order in which different types of callbacks are executed. |
130 | 127 | * `process.nextTick()` and Promises' microtask queue provide a way to schedule code to run immediately after the current operation, but before the event loop continues. |
| 128 | + |
| 129 | +**setTimeout() vs setImmediate()** |
| 130 | + |
| 131 | +In main module, the order of execution is non-deterministic, as it is bound by the performance of the process |
| 132 | + |
| 133 | +```javascript |
| 134 | +setTimeout(() => { |
| 135 | + console.log("timeout") |
| 136 | +}, 0) |
| 137 | + |
| 138 | +setImmediate(() => { |
| 139 | + console.log("immediate") |
| 140 | +}) |
| 141 | +``` |
| 142 | + |
| 143 | +Within an I/O cycle, the immediate callback is always executed first. |
| 144 | + |
| 145 | +```javascript |
| 146 | +const fs = require("fs") |
| 147 | +fs.readFile(".prettierc.json", () => { |
| 148 | + setTimeout(() => { |
| 149 | + console.log("timeout") |
| 150 | + }, 0) |
| 151 | + setImmediate(() => { |
| 152 | + console.log("immediate") |
| 153 | + }) |
| 154 | +}) |
| 155 | +``` |
| 156 | +**process.nextTick()** |
| 157 | + |
| 158 | +process.nextTick() will be processed after the current operation is completed, regardless of current phase of the event loop. |
| 159 | +Operation is defined as a transition from the underlying C/C++ handler, and handling the JavaScript that needs to be executed. |
| 160 | + |
| 161 | +* process.nextTick() fires immediately on the same phase |
| 162 | +* setImmediate() fires on the following iteration or 'tick' of the event loop |
| 163 | + |
| 164 | +**Why use process.nextTick()?** |
| 165 | + |
| 166 | +* Allow users to handle errors, cleanup unneeded resources, or try the request again before the event loop continues. |
| 167 | +* At times to allow a callback to run after the call stack has unwound but before the event loop continues. |
| 168 | + |
| 169 | +```javascript |
| 170 | +setImmediate(() => { |
| 171 | + console.log("immediate") |
| 172 | +}) |
| 173 | +console.log("console") |
| 174 | +process.nextTick(() => { |
| 175 | + console.log("process tick") |
| 176 | +}) |
| 177 | + |
| 178 | +/* |
| 179 | +process tick |
| 180 | +immediate |
| 181 | +*/ |
| 182 | +``` |
| 183 | + |
| 184 | +* process.nextTick() -> execute code immediately on the same phase |
| 185 | +* setImmediate() -> execute code at the end of the current event loop cycle. |
| 186 | +* setTimeout()-> execute after a designated amount of milliseconds. |
| 187 | +* setInterval() -> execute multiple times |
| 188 | + |
| 189 | +```javascript |
| 190 | +const timeoutObj = setTimeout(() => { |
| 191 | + console.log("timeout beyond time") |
| 192 | +}, 1500) |
| 193 | + |
| 194 | +const immediateObj = setImmediate(() => { |
| 195 | + console.log("immediately executing immediate") |
| 196 | +}) |
| 197 | + |
| 198 | +const intervalObj = setInterval(() => { |
| 199 | + console.log("interviewing the interval") |
| 200 | +}, 500) |
| 201 | + |
| 202 | +clearTimeout(timeoutObj) |
| 203 | +clearImmediate(immediateObj) |
| 204 | +clearInterval(intervalObj) |
| 205 | +``` |
0 commit comments