0

嗨,我是节点新手,我正在尝试了解如何处理节点进程。我已经读过应该不惜一切代价避免同步方法,并且需要编译/缓存文件并且后续调用使用缓存而不是每次从磁盘读取。

在ExpressJS存储库的 MVC 示例中的引导文件的第 7 行,有一个对 readdirSync 的调用,它循环所有控制器并实例化它们以动态创建路由。

当向服务器发出请求时,会发生什么?

a) 启动应用程序编译/缓存它,路由和回调存储在内存中以服务所有未来的请求。

b) 引导运行每个请求,每次调用服务器时从磁盘读取控制器并实例化。

c) 别的?

如果它是一个,我可以理解为什么作者会使用同步调用。代码更干净,并且在 init 阶段阻塞并不像在请求期间阻塞那么糟糕。如果是 b,在每个请求开始时阻塞不会极大地影响性能吗?

谢谢!

4

2 回答 2

2

该文件在初始化期间运行,并且仅运行一次。你可以在这里看到:

require('./lib/boot')(app, { verbose: !module.parent });

在 Node 中,您通常不想阻塞主事件循环,这是同步函数倾向于做的事情。例如,假设您有一个加载文件的 HTTP 处理程序:

app.get('/', function(req, res) {
  res.send(fs.readFileSync('./file.log'));
});

这是同步完成的,并且会阻塞事件循环,直到文件完全加载,从而阻止处理任何其他 HTTP 请求。因此,我们一般在初始化的时候把东西缓存到内存中,防止阻塞。

如果在初始化期间缓存,则文件只加载一次。

var file = fs.readFileSync('./file.log');
app.get('/', function(req, res) {
  res.send(file);
});

但另一种方法是使用异步读取:

app.get('/', function(req, res) {
   fs.readFile('./file.log', function(err, data) {
     res.send(data);
   });
});

您通常不想这样做,因为如果您有大量请求怎么办?你会浪费 I/O 一遍又一遍地从磁盘读取同一个文件。

于 2013-09-17T16:33:30.397 回答
1

这是 a) 发生了。你的假设都是正确的。同步调用更干净,它只在初始化期间发生一次。Express 小心不要在请求处理程序中进行任何 io 阻塞。

于 2013-09-17T16:31:54.427 回答