Nodejs 新手,这是我对 Node.js 执行顺序的理解,希望各位指正

发布于 1周前 作者 sinazl 来自 nodejs/Nestjs

Nodejs 新手,这是我对 Node.js 执行顺序的理解,希望各位指正

第一个问题:Node的整体执行顺序是什么呢?

是这样么:

  1. 一开始从我们的code入口开始,以同步,顺序执行的方式执行我们的代码。
  2. 如果其中存在 I/O 则被放入 事件队列,I/O交给操作系统,执行完毕后,会把回调放入事件队列,Node继续执行我的主线程代码
  3. 然后我的代码被整个跑过一遍(不会阻塞等待IO),即凡是不涉及I/O的部分,被跑过一遍。
  4. 代码跑完后,余下的就是事件和事件回调的逻辑,于是Node事件循环(Event Loop)不断的检查队列中的事件,如果检测到,则交给主线程运行其回调的逻辑。

总结: 密集的I/O会交给别的线程独立负责,但是如果主线程中出现特别耗时的执行,那么就会耽搁队列中事件的执行(这个模型决定的),但是整体上,CPU利用率增高了,内存的开销减少了(相比传统多线程,还是这个模型决定的),由于减少了线程创立,上下文切换,所有Node的资源占用少,CPU使用率高也就是性能高。所以Node如果用来做以JSON数据交换为主,接受密集网络请求的服务器(比如:社交网站的手机m站)性能会很好。密集计算不适合Node。

其实上面的流程,也就是我对:

“Everything runs in parallel except your code! (在Node中)除了你的代码,一切都是并行的!”

这句话的理解。


我的理解对么? 请各位大神指正


15 回复

码一下。围观

感觉大体没错。

但是
于是 Node 事件循环( Event Loop )

这一段,应该是利用类似 epoll 的技术吧?

暴露给 js 是一个回调函数,往下一层是 event-loop ,再往下是多线程。我的理解,如果有误请指正。
我们不需要关心 I/O 在后台是如何工作的,但是由于我们的计算机硬件的工作方式,线程是处理器最基本的执行单元, libuv 和操作系统通常会运行后台 /工作者线程, 或者采用非阻塞方式来轮流执行任务。

talk is cheap , show me the code

应该不是只有 io 是异步的

基本是正确的,改正一个地方:

你总结里写的,“多个线程”这个概念是错误的,不管是 Node 还是浏览器的 JS 都是单线程的,这点始终要清楚,至于 Event Loop 这块,你说的基本对但是表达上还是有些模糊,可以看一下 EU JSConf 这个关于 EventLoop 的这块, http://2014.jsconf.eu/speakers/philip-roberts-what-the-heck-is-the-event-loop-anyway.html ,给别人安利过 N 次了……

看完回来回复,五星好评,运作机理如此清晰!!!感谢

不对,是首先初始化全局的队列,然后把入口的函数塞进去。之后的逻辑就是队列不为空就取出来执行,执行过程中还有可能往里塞东西(跟 bfs 似的)

你拿 libuv 写写项目就明白了。。

eventloop 会串行按顺序执行队列里的东西,没有线程的上下文切换。。

好牛逼的理解,才新手就有这等理解,后生可畏啊!

大循环 + 优先队列 + poll

你好,很高兴看到你对Node.js的执行顺序有所理解。Node.js是基于事件驱动和非阻塞I/O模型的,因此理解其执行顺序对于新手来说确实很重要。

在Node.js中,代码的执行顺序通常是由事件循环(Event Loop)来管理的。以下是一个简单的示例,帮助你更好地理解:

console.log('Start');

setTimeout(() => {
  console.log('Timeout');
}, 1000);

console.log('Synchronous code');

// 假设这里有一个异步的HTTP请求
const http = require('http');
http.get('http://example.com', (res) => {
  console.log('HTTP response received');
}).on('error', (e) => {
  console.error(`Got error: ${e.message}`);
});

console.log('End');

输出顺序可能是:

Start
Synchronous code
End
(After 1 second) Timeout
(After HTTP response is received) HTTP response received

在这个例子中:

  1. 同步代码会立即执行。
  2. setTimeout设置的回调函数会在指定的延时后执行。
  3. 异步的HTTP请求会在请求完成后执行回调函数。

事件循环会不断检查是否有待处理的回调,并按顺序执行它们。这就是Node.js能够处理大量并发连接而不需要为每个连接创建新线程的原因。

希望这个解释能帮助你更好地理解Node.js的执行顺序。如果有任何疑问或需要进一步的解释,请随时提问!

回到顶部