我知道在节点中进行开发时,应始终尝试避免阻塞(同步)功能并使用异步功能,但是我进行了一些测试,以了解它们之间的比较。
我需要打开一个包含i18n数据(例如日期和时间格式等)的json文件,并将该数据传递给使用该数据 在我的视图中格式化数字等的类。
开始将所有类的方法包装在回调中会很尴尬,因此,如果可能的话,我将改用同步版本。
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');
This results in the following lines in my console:
two: 1ms one: 159ms
看来fs.readFileSync比fs.readFile快150倍,并且加载50KBjson文件(最小化)大约需要1毫秒。我所有的json文件约为50-100KB。
我在想也许还以某种方式将这个json数据存储或保存到会话中,以便每个会话(或当用户更改其语言环境时)仅读取一次文件。我不完全确定该怎么做,这只是一个想法。 fs.readFileSync在我的情况下可以使用还是以后会遇到麻烦?
fs.readFileSync
不,您无法在节点服务器中使用阻塞API调用。 您的网站对许多并发连接的响应能力将受到重大 打击。这也公然违反了节点的第一原则。
节点工作的关键在于,当它等待IO时,它同时在执行CPU /内存处理。这仅需要异步调用。因此,如果有100个客户端读取100个JSON文件,则节点可以要求操作系统读取这100个文件,但是在等待操作系统返回可用文件数据时,节点可以处理这100个网络请求的其他方面。如果您只有一个同步调用,则在该操作完成时,所有客户端处理将完全停止。因此,当您 依次读取客户端1、2、3、4等的文件时,客户端编号100的连接将等待任何处理。这是维尔维尔。
这是另一个比喻。如果您去一家餐馆而且是唯一的顾客,那么如果一个人坐着,接您的订单,将其烹饪,送达给您,并处理账单,而没有与房东/女主人,服务员,厨师长,厨师,收银员等。但是,餐厅有100位顾客,额外的协调意味着事情并行发生,餐厅的整体响应能力大大提高,超过了一个人的情况。试图自己处理100个客户。