Node.Js是否所有的同步调用都保证在异步调用之前执行?

问题描述:

我是新来的NodeJS,我试图让我的头周围的事件循环在各种情况下如何工作的。Node.Js是否所有的同步调用都保证在异步调用之前执行?

采取以下代码片段:

console.log("Hello"); 

setImmediate(() => { 
    console.log("Immediate"); 
    }); 

console.log("World"); 

它提供了以下的输出:

Hello 
World 
Immediate 

它才有意义,如果你愿意相信所有的异步调用所有同步调用后发生。

是真的吗?所有节点同步调用都假设在异步调用之前执行。

何时事件循环事件开始?解析整个文件或节点运行时启动后?或者当它遇到第一个异步调用?

我能理顺上面的输出只有当我接受推定的一个,要么全部异步调用同步调用之后发生,即。事件循环在所有同步呼叫完成后启动,或者setImmediate()这里需要更多时间才能完成比console.log()

哪一个是正确的?

+1

,如果你认为它作为一个队列这是有道理的 – maioman

+0

这个问题有点过于开放可以很容易地回答。这听起来像你需要去阅读关于事件循环的好资源,然后回来一个更具体的问题。虽然有很好的资源,谷歌可能会与https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop – Deadron

+0

它是什么,你认为'setImmediate'实际上是在做开始? –

调用堆栈由同步调用(console.log)填充,事件队列使用异步调用填充(setImmediate)。调用堆栈必须在事件循环处理事件队列之前清空。这是有效的程序是什么样子的调用堆栈和事件队列:

状态1:

stack      queue 
[console.log('Hello')]  [setImmediate(() => ...)] 
[console.log('World')] 

状态2:

stack      queue 
[console.log('World')]  [setImmediate(() => ...)] 

状态3:

stack      queue 
          [setImmediate(() => ...)] 

状态4(事件循环出队并推动调用堆栈):

stack      queue 
[console.log('Immediate')] 

状态5(完成):

stack      queue 

你可以看到它的一个更准确的动画在这里:http://latentflip.com/loupe/?code=Y29uc29sZS5sb2coJ0hlbGxvJykKCnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7CiAgICBjb25zb2xlLmxvZygnSW1tZWRpYXRlJykKfSwgMCkKCmNvbnNvbGUubG9nKCdXb3JsZCcp!!!PGJ1dHRvbj5DbGljayBtZSE8L2J1dHRvbj4%3D

JavaScript是单线程的,这意味着它只有一个调用堆栈。浏览器(和节点)提供异步API以将可能阻塞的项目从调用堆栈中移出并将它们移动到事件队列中,以便引擎可以继续处理调用堆栈(并且不冻结浏览器/服务器)并有效地“背景”长 - 运行或阻止操作。

+0

检查你的链接, 请仔细看看,在setTimeout和console.log之前有一段短暂的时间,堆栈将为空,并且队列中会有一个函数。在这一点上,你可以将setTimeout函数放入callstack而不是console.log中,为什么不这样做呢?这就是我的全部问题 –

+0

您刚刚向我展示了您可以在理论上放置setImmediate,然后执行任何其他代码 –

+0

是的,它可以_could_,但这不是它实际上做的。事件队列是这种单线程语言如何避免阻塞 –