我知道当在node中开发时,你应该总是尽量避免阻塞(sync)函数,而使用async函数,但是,我做了一个小测试来比较它们。
我需要打开一个包含i18 n数据(如日期和时间格式等)的JSON文件,并将该数据传递给一个类,该类使用该数据来格式化视图中的数字等。
在回调中开始 Package 类的所有方法会有点笨拙,所以如果可能的话,我将使用同步版本。
console.time('one');
console.time('two');
fs.readFile( this.dir + "/" + locale + ".json", function (err, data) {
if (err) cb( err );
console.timeEnd('one');
});
var data = fs.readFileSync( this.dir + "/" + locale + ".json" );
console.timeEnd('two');
这将在我的控制台中生成以下行:
two: 1ms
one: 159ms
看起来fs.readFileSync比fs.readFile快150倍-加载一个50 KB的JSON文件(缩小版)大约需要1毫秒。我所有的JSON文件都在50- 100 KB左右。
我还在想,也许可以通过某种方式将这些JSON数据存储或保存到会话中,以便每个会话(或当用户更改他们的区域设置时)只读取一次文件。我不完全确定如何做到这一点,这只是一个想法。
在我的情况下使用fs.readFileSync
可以吗?或者以后会遇到麻烦吗?
5条答案
按热度按时间jjjwad0x1#
不,在你描述的节点服务器中使用阻塞API调用是不对的。你的站点对许多并发连接的响应将受到巨大的打击。这也公然违反了节点的第一原则。
节点工作的关键是,当它等待IO时,它同时进行CPU/内存处理。这需要专门的异步调用。因此,如果您有100个客户端阅读100个JSON文件,节点可以要求操作系统读取这100个文件,但在等待操作系统返回可用的文件数据时,节点可能正在处理这100个网络请求的其他方面。如果您有一个同步调用,则在该操作完成时,所有客户端处理都将完全停止。因此,当您读取客户端1、2 3,4,依次类推,这是费维尔。
再打个比方。如果你去一家餐馆,而且你是唯一的顾客,那么如果一个人坐在你旁边,接受你的订单,烹饪它,为你服务,并处理账单,而不需要与主人/女主人、服务员、主厨、一线厨师、收银员等打交道的协调开销,你可能会得到更快的服务。然而,如果餐馆里有100名顾客,额外的协调意味着事情并行地发生,并且餐馆的整体响应性被增加,远远超过了如果单个人试图独自处理100个顾客的情况。
v9tzhpje2#
您正在使用同步读取阻塞异步读取的回调,请记住单线程。现在我明白时间差异仍然很惊人,但您应该尝试读取长得多的文件,并想象许多许多客户端也会这样做,只有这样开销才会得到回报。这应该会回答您的问题,是的,如果你用阻塞的IO来处理成千上万的请求,你会遇到麻烦。
prdp8dxp3#
是的,这是正确的,在服务器端环境中处理异步方式。但是如果他们的用例不同,比如在客户端JS项目中生成构建,同时阅读不同风格的JSON文件。
虽然我们需要一种快速的方式来创建一个用于部署的小型构建(这里同步就进入了画面),但它并没有太大的影响。for more info and library
uyhoqukh4#
经过大量的时间和大量的学习和实践,我已经尝试了一次,我已经找到了答案,我可以展示一些例子:
polhcujo5#
我试着去检查真实的的,fs.readFileSync之间速度的可测量差异()和文件系统.readFile()用于下载SD卡上的3个不同文件,我在此之间添加了一些数学计算,我不我不明白哪里是速度的差异,这是总是显示在节点图片时,节点是更快的,也在简单的操作,如下载3次相同的文件和时间操作接近下载1次此文件所需的时间。
我明白,这无疑是有用的,服务器在下载一些文件时能够做其他工作,但很多时候在YouTube或在书中有一些图表是不精确的,因为当你有一个像下面的异步节点的情况是缓慢的,然后在阅读小文件同步(如下面:85千字节、170千字节、255千字节)。