Node.Js是否所有的同步调用都保证在异步调用之前执行?
我是新来的NodeJS,我试图让我的头周围的事件循环在各种情况下如何工作的。Node.Js是否所有的同步调用都保证在异步调用之前执行?
采取以下代码片段:
console.log("Hello");
setImmediate(() => {
console.log("Immediate");
});
console.log("World");
它提供了以下的输出:
Hello
World
Immediate
它才有意义,如果你愿意相信所有的异步调用所有同步调用后发生。
是真的吗?所有节点同步调用都假设在异步调用之前执行。
何时事件循环事件开始?解析整个文件或节点运行时启动后?或者当它遇到第一个异步调用?
我能理顺上面的输出只有当我接受推定的一个,要么全部异步调用同步调用之后发生,即。事件循环在所有同步呼叫完成后启动,或者setImmediate()
这里需要更多时间才能完成比console.log()
哪一个是正确的?
调用堆栈由同步调用(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
JavaScript是单线程的,这意味着它只有一个调用堆栈。浏览器(和节点)提供异步API以将可能阻塞的项目从调用堆栈中移出并将它们移动到事件队列中,以便引擎可以继续处理调用堆栈(并且不冻结浏览器/服务器)并有效地“背景”长 - 运行或阻止操作。
检查你的链接, 请仔细看看,在setTimeout和console.log之前有一段短暂的时间,堆栈将为空,并且队列中会有一个函数。在这一点上,你可以将setTimeout函数放入callstack而不是console.log中,为什么不这样做呢?这就是我的全部问题 –
您刚刚向我展示了您可以在理论上放置setImmediate,然后执行任何其他代码 –
是的,它可以_could_,但这不是它实际上做的。事件队列是这种单线程语言如何避免阻塞 –
,如果你认为它作为一个队列这是有道理的 – maioman
这个问题有点过于开放可以很容易地回答。这听起来像你需要去阅读关于事件循环的好资源,然后回来一个更具体的问题。虽然有很好的资源,谷歌可能会与https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop – Deadron
它是什么,你认为'setImmediate'实际上是在做开始? –