堆栈如何在NodeJ上工作?

问题描述:

我最近开始阅读NodeJS(和JS),并且对于如何在NodeJs中调用回调有点困惑。假设我们做这样的事情:堆栈如何在NodeJ上工作?

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

输出:“Hello World”的

到目前为止,在我读过JS是单线程的,因此事件循环是怎么回事,虽然一个大筹码,而且我也被告知不要在回调函数中使用大的调用。

1)

好了,我的第一个问题是假设它的一个堆栈不回调函数得到由主事件循环的线程中运行?如果是的话,如果我们有一个通过回调提供内容的站点(从数据库提取并推送请求),并且我们有1000个并发,那1000个用户基本上是同步服务的,主线程在每个回调函数中执行计算,然后继续主事件循环?如果是这种情况,这个并发性究竟如何?

2)如何被添加到堆栈中的回调函数,因此,可以说我的代码是这样的:

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

则不会回调函数被添加到堆栈中的超时甚至发生过吗?如果是的话是否有一个标志被设置,通知主线程回调函数已准备就绪(或者是否有其他机制)。如果事实上发生了什么事情,它不会使堆栈膨胀,尤其是对于具有回调函数的大型Web应用程序而言,堆栈越大,从线程必须遍历整个事物所需的所有时间越长。

事件循环不是堆栈。它可以更好地被认为是一个队列(先入先出)。最常见的用法是执行I/O操作。

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

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

对于具体的setTimeout的情况,可以认为它像一个优先级队列。节点不会考虑将项目/作业/回调出队,直到至少时间过去。

在Node/JavaScript事件循环中有很多优秀的文章,如果您感到困惑,您可能需要阅读它们。

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