Did you ever wonder what's going on behind the scenes when you run a very small piece of code in JavaScript? I actually didn't for a long time.
I...
For further actions, you may consider blocking this person and/or reporting abuse
Very nice explanation!
One small addition that I'd like to make is "Hoisting". Even before the code execution begins, all variable and function declarations are hoisted (in simpler terms, moved) to the top of the file.
Looking at your very first example, if we make a small change to the code, like so
Even though it may seem a bit counter-intuitive, the code still runs exactly as before. This is because the function declaration is moved to the top of the file before execution. Note that only declarations are hoisted, and not definitions, so if you're assigning any values to some variables, the assignments still stay in the place where you wrote them, it's just that the declaration statement with an undefined value is moved to the top of the file.
Speaking of declarations vs. definitions, one little caveat that has caught me off guard in the past, is with arrow functions. In the above code
getTotalFruits
is a function, since it is declared with thefunction
keyword, but if we change it to an arrow function,the code throws a
ReferenceError
. This is because,getTotalFruits
is now technically a regular variable which is assigned an anonymous function.Hope you and anyone reading find this useful.
Cheers!
Genius
Very useful addition, Gaurav! You enlightened us. Definitely I benefit from your explanation.
Thank you for your contribution 🤟
Very cool, thanks!
Question: what if we put the
console.log(..)
statement beforefetchData.then(..)
? The call stack is empty afterconsole.log
and even though thefetchData
promise is already done, we haven't putshowData
on the microtask stack, sorunTimer
will be first?Hi, thanks!
If I understand the question, I will try to explain.
Settimeout, console.log, fetch... this is the calling order in your question.
First Scenerio: Fetching takes 200ms time and consoling takes 250ms:
-- setTimeout communicates with Web API
-- console.log is in Call Stack. [0ms]
-- runTimer is ready waiting in Callback Queue [0ms]
-- fetch communicates with Web aPI [1ms]
-- showData is ready waiting in Microtask Queue [200ms]
-- console.log run and consoled and removed from Call Stack [250ms]
-- showData run in Call Stack [251ms]
-- runTimer run in Call Stack [252ms]
Second Scenerio: Fetching takes 300ms time and consoling takes 250ms:
-- setTimeout communicates with Web API
-- console.log is in Call Stack. [0ms]
-- runTimer is ready waiting in Callback Queue [0ms]
-- fetch communicates with Web aPI [1ms]
-- console.log run and consoled and removed from Call Stack [250ms]
-- runTimer run in Call Stack [251ms]
-- showData is ready waiting in Microtask Queue [300ms]
-- showData run in Call Stack [301ms]
I guess, it is something like that. :)
Interesting. The second scenario is clearly correct because the fetchData promise isn't done when console.log finishes, so runTimer gets picked up from the callback queue.
I'm not so sure about the first scenario... Suppose you never call
fetchData.then(showData)
then showData will never run (obviously). Now, suppose you keep the fetchData promise object around for a while, do a bunch of stuff (a for loop logging "hello" to the console a few thousand times), and only then callfetchData.then(showData)
. Surely, therunTimer
callback would have had the chance to get picked up from the callback queue, after one of theconsole.log("hello")
calls in the loop, when the call stack is empty, and there's nothing on the microtask queue yet.My version: Fetching takes 200ms time and consoling takes 250ms:
-- setTimeout communicates with Web API
-- console.log is in Call Stack. [0ms]
-- runTimer is ready waiting in Callback Queue [0ms]
-- fetch communicates with Web aPI [1ms]
-- console.log run and consoled and removed from Call Stack [250ms]
-- runTimer run in Call Stack [251ms]
-- fetchData promise puts showData on microtask queue [251ms]
-- showData is ready waiting in Microtask Queue [251ms]
-- showData run in Call Stack [251ms]
Maybe I should just test it and post the results here :)
You might be right 🙂 but probably, Call Stack will never be empty during the for loop. Therefore runTimer cannot find a chance to jump in Call Stack.
One of the reasons that I guess like that:
for loop is inside Call Stack as a whole code block, so while passing from one console.log to another one, Call stack is not actually empty at any moment.
But as you said, the best way to learn is testing. If you test it, please let us know the results here ✌️
Thank you so much, it's worth reading
Thank you 🙏
Сongratulations 🥳! Your article hit the top posts for the week - dev.to/fruntend/top-10-posts-for-f...
Keep it up 🫰
Thank you for sharing 🤟✌️
very well explained. Thanks.
Understanding these basics save you a lot of trouble later. Been there 😅
I totally agree with this 🙂 thank you!
probably the best explanation!
thank you Joshi! 🙂
amazing!
Thank you for sharing!
Amazing! Thank you :)
Thanks! 🙏
Thanks for the explanation, really clear and straight forward.
Glad to hear you liked it, thanks!
Very nice and simple explanation! I like it. ❣️
Glad you like it, thanks Zakariya 🙏