|
| 1 | +# Chapter 20: Trust Issues with setTimeout() |
| 2 | + |
| 3 | +```javascript |
| 4 | +console.log("Start"); |
| 5 | + |
| 6 | +setTimeout(function cb() { |
| 7 | + console.log("Callback"); |
| 8 | +}, 5000); |
| 9 | + |
| 10 | +console.log("End"); |
| 11 | +``` |
| 12 | + |
| 13 | +`setTimeout` sometimes does not exactly guarantee that the callback method will be called exactly after 5s. |
| 14 | +Maybe 6,7 or even 10! It all depends on callstack |
| 15 | + |
| 16 | +While execution of program |
| 17 | + |
| 18 | +- First GEC is created and pushed in callstack. |
| 19 | +- Start is printed in console |
| 20 | +- When `setTimeout` is seen, callback method is registered into webapi's env. And timer is attached to it and started. `cb` waits for its turn to be execeuted once timer expires. |
| 21 | +- But JS waits for none. Goes to next line. |
| 22 | +- End is printed in console. |
| 23 | +- After "End" suppose we have 1 million lines of code that runs for 10 sec(say). So GEC won't pop out of stack. It runs all the code for 10 sec. |
| 24 | +- But in the background, the timer runs for 5s. While callstack runs the 1M line of code, this timer has already expired and `cb` fun has been pushed to Callback queue. |
| 25 | +- Event loop keeps checking if callstack is empty or not. But here GEC is still in stack so `cb` can't be popped from callback Queue and pushed to CallStack. |
| 26 | +- **Though `setTimeout` is only for 5s, it waits for 10s until callstack is empty before it can execute**(When GEC popped after 10sec, `cb()` is pushed into call stack and **immediately executed** (Whatever is pushed to callstack is executed instantly)) |
| 27 | +- This is called as the **Concurrency model of JS**. This is the logic behind `setTimeout`'s trust issues |
| 28 | + |
| 29 | +### The First rule of JavaScript |
| 30 | + |
| 31 | +- **Do not block the main thread** (as JS is a single threaded(only 1 callstack) language) |
| 32 | + |
| 33 | +- This raises a question. _Why not add more call stacks and make it multithreaded?_ |
| 34 | +- JS is a synchronous single threaded language. And thats its beauty. With just 1 thread it runs all pieces of code there. It becomes kind of an interpreter language, and runs code very fast inside browser (no need to wait for code to be compiled) (JIT - Just in time compilation). And there are still ways to do async operations as well. |
| 35 | + |
| 36 | +### Now what if the timeout = 0sec |
| 37 | + |
| 38 | +```javascript |
| 39 | +console.log("Start"); |
| 40 | + |
| 41 | +setTimeout(function cb() { |
| 42 | + console.log("Callback"); |
| 43 | +}, 0); |
| 44 | + |
| 45 | +console.log("End"); |
| 46 | +``` |
| 47 | + |
| 48 | +- Even though `timer = 0s`, the `cb()` has to go through the queue. Registers calback in webapi's env , moves to callback queue, and execute once callstack is empty |
| 49 | + |
| 50 | + Start |
| 51 | + |
| 52 | + End |
| 53 | + |
| 54 | + Callback |
| 55 | + |
| 56 | +- This method of putting `timer = 0`, can be used to defer a less imp fun by a little so the more important fun (here printing "End") can take place |
| 57 | + |
| 58 | +--- |
| 59 | + |
| 60 | +<br><br> |
| 61 | + |
| 62 | +<p align="left"> |
| 63 | + <a href="./19_JS_Engine_And_ChromeV8.md"><b>‹ GO TO PREVIOUS</b></a> |
| 64 | +</p> |
| 65 | + |
| 66 | +<p align="right"> |
| 67 | + <a href="./21_Higher_Order_Functions_And_Functional_Programming.md"><b>GO TO NEXT ›</b></a> |
| 68 | +</p> |
| 69 | + |
| 70 | +--- |
0 commit comments