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

时间:2017-09-14 14:28:04

标签: javascript node.js

我是NodeJS的新手,我正试图了解事件循环在各种情况下的工作原理。

请使用以下代码段:

console.log("Hello");

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

console.log("World");

它提供以下输出:

Hello
World
Immediate

只有在您愿意相信所有同步调用都发生所有同步调用之后才有意义。

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

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

只有当我接受其中一个假设时,我才能合理化上述输出,或者在同步调用之后发生所有异步调用,即。所有同步调用完成后,事件循环开始,或者setImmediate()此处需要的时间比console.log()

更长

哪一个是正确的?

1 个答案:

答案 0 :(得分:2)

从同步调用(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以从调用堆栈中取出可能阻塞的项目并将它们移动到事件队列,以便引擎可以继续处理调用堆栈(而不是冻结浏览器/服务器)并且有效地“后台”长 - 运行或阻止操作。