Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question, not issue :) #17

Closed
AndriyYakymiv opened this issue Jan 3, 2019 · 8 comments
Closed

Question, not issue :) #17

AndriyYakymiv opened this issue Jan 3, 2019 · 8 comments

Comments

@AndriyYakymiv
Copy link

As it is written in the MDN's article: When the stack is empty, a message is taken out of the queue and processed.

But I've noticed strange thing which I don't understand.

For example:

function f() {
  console.log("foo");
  setTimeout(g, 0);
  console.log("foo again");
}
function g() {
  console.log("bar");
}
function b() {
  console.log("bye");
}

f();
/*<---- Why the stack is not empty here, after f() function removing from stack? */
b();

Output is next and it is correct order:

foo
foo again
bye
bar

But why the g() function in setTimeout runs only after b() function despite the fact that call stack is empty? Or it's not? In your demo it's empty

Another example based on thoughts from previous:
So can I presume that if I have a Promise it means that .then() part with resolve or error will run only after all synchronous code will finish because it won't be added to the call stack from callback queue because it's not empty? Or it is?

That's why I have a question: when exactly call stack becomes fully empty?

@AndriyYakymiv
Copy link
Author

Thank you in advance if somebody will help me to understand 😃

@vuau
Copy link

vuau commented Jan 8, 2019

why the g() function in setTimeout runs only after b() function

  • after console.log("foo"); JS execute setTimeout and from now on g() is handled by the timer. After 0 second, g() is put into the callback queue waiting until the stack is empty to be executed
  • JS execute console.log("foo again");
  • JS execute b() then console.log("bye")
  • Call stack is empty now. Browser put g() into the call stack and JS execute it.
  • JS execute console.log("bar");

@AndriyYakymiv
Copy link
Author

@phamvuau
But why call stack is not empty after finish of f() function?

In demo it's empty: Check latenflip

Does the engine add all of the synchronous code instructions from main thread(or main function which wraps the code) to some "virtual queue" which passes this all instructions step by step to call stack and after only running all such instructions from this "queue" event loop will pass functions from callback queue to call stack?

@vuau
Copy link

vuau commented Jan 8, 2019

@AndriyYakymiv it's empty in my side. I'm using Chrome latest.

Does the engine add all of the synchronous code instructions from main thread(or main function which wraps the code) to some "virtual queue" which passes this all instructions step by step to call stack and after only running all such instructions from this "queue" event loop will pass functions from callback queue to call stack?

There is a message queue or we can call it callback queue. You can find more detail on MDN

@AndriyYakymiv
Copy link
Author

@phamvuau
In this demo it's also empty and I know that this is correct behavior. But according to MDN's article: When the stack is empty, a message is taken out of the queue and processed. This queue - is a callback queue, I know it. But then why after finishing the f() function result of SetTimeout() is not added to call stack from callback queue but instead the g() function is added? You are also saying that the call stack after f() is empty

@latentflip
Copy link
Owner

@AndriyYakymiv I think the best way to think of it is like this, and perhaps loupe should actually show this:

instead of this

function f() {
  console.log("foo");
  setTimeout(g, 0);
  console.log("foo again");
}
function g() {
  console.log("bar");
}
function b() {
  console.log("bye");
}

f();
/*<---- Why the stack is not empty here, after f() function removing from stack? */
b();

think about it like this:

function main() {
  function f() {
    console.log("foo");
    setTimeout(g, 0);
    console.log("foo again");
  }
  function g() {
    console.log("bar");
  }
  function b() {
    console.log("bye");
  }

  f();
  b();
}

main()

so think of your whole script as if it was wrapped in a big function. Then you would have a main() item at the bottom of the stack all the way through f() and b(), and it would only clear after b() was done.

@vuau
Copy link

vuau commented Jan 8, 2019

The JS runtime still executing the main function so it simply moves on next statement. If you put a break point in Chrome dev tool, you can see the call stack and the anonymous function which is the entry point for the execution.

@AndriyYakymiv
Copy link
Author

@phamvuau @latentflip
I understood, every script creates an anonymous wrapped function which is inside the call stack and all callback functions added to call stack from callback queue only after this "main"(anonymous) function will execute all instructions. If I understand it correctly, you can close this issue 😃. Thank you, guys!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants