堆栈如何在NodeJ上运行?

时间:2013-04-11 02:06:40

标签: node.js

我最近开始阅读NodeJS(和JS),并且对于如何在NodeJ中使用回调感到困惑。假设我们做这样的事情:

setTimeout(function(){
    console.log("World");
},1000);
console.log("Hello");

输出:“Hello World”

到目前为止我读过的内容 JS是单线程的,所以事件循环通过一个大堆栈,我也被告知不要在回调函数中调用大调。

1)

好的,所以我的第一个问题是假设它的一个堆栈是否由主事件循环线程运行回调函数?如果是这样,那么如果我们有一个站点通过回调提供内容(从db和pushes请求获取),并且我们有1000个并发,那些1000个用户基本上是同步服务的,其中主线程进入每个回调函数中计算然后继续主事件循环?如果是这种情况,这究竟是如何并发的?

2)如何将回调函数添加到堆栈中,所以假设我的代码如下:

setTimeout(function(){
    console.log("Hello");
},1000);
setTimeout(function(){
    console.log("World");
},2000);

然后在超时甚至发生之前将回调函数添加到堆栈中?如果是这样,那么设置了一个标志,通知主线程回调函数已准备就绪(或者是否有另一种机制)。如果这是事实上发生的事情并不是它只是膨胀堆栈,特别是对于具有回调函数的大型Web应用程序,并且堆栈越大,运行所需的时间越长,因为线程必须逐步完成整个事情。

2 个答案:

答案 0 :(得分:1)

回调函数未添加到调用者堆栈。这里没有递归。它们是从事件循环中调用的。尝试在示例中替换console.log并观察结果 - 堆栈不会增长。

答案 1 :(得分:1)

事件循环不是堆栈。可以更好地将其视为队列(先进/先出)。最常见的用法是执行I / O操作。

想象一下,您想要从磁盘读取文件。你首先说嘿,我想阅读这个文件,当你完成阅读时,请调用此回调。虽然实际的I / O操作是在一个单独的进程中执行的,但Node应用程序可以自由地继续执行其他操作。文件读完后,会在事件循环队列中添加一个项目,表示完成。节点应用程序可能仍在忙于执行其他操作,或者可能有其他项目等待首先出列,但最终我们的完成通知将由节点的事件循环出列。它将与我们的回调匹配,然后将按预期调用回调。当回调返回时,事件循环使下一个项目出列并继续。当节点的事件循环中没有任何内容时,应用程序退出。

这是事件循环如何工作的粗略近似,而不是确切的技术描述。

对于特定的setTimeout情况,请将其视为优先级队列。节点不会考虑将项目/作业/回调出列,直到至少已经过了这段时间。

Node / JavaScript事件循环上有很多很棒的文章,如果你感到困惑,你可能想要阅读它们。