让我们想象一个异步函数,它首先加载一个文件,然后再与它进行异步处理。该函数无法在没有文件的情况下继续,因此我的假设是加载此文件可以同步完成(*):
const asyncFnWithSyncCode(filePath, next) {
// Load file
const file = fs.readFileSync(filePath)
// Continue to process file with async functions
// ...
next(null, processedFile)
}
对于不同的文件,可以多次调用 asyncFnWithSyncCode
:
async.parallel([
(done) => { asyncFnWithSyncCode('a.json', done) },
(done) => { asyncFnWithSyncCode('b.json', done) },
(done) => { asyncFnWithSyncCode('c.json', done) }
], next)
我的问题是:这对性能有何影响?同步功能是否会导致其他readFileSync
被延迟?它会产生什么影响吗?
欢迎提供最佳实践,资源和意见。谢谢!
(*)我知道我可以简单地使用异步readFile
- 版本,但我真的想知道它在这种特殊结构中是如何工作的。
答案 0 :(得分:3)
同步功能是否会导致其他
readFileSyncs
延迟?
是。 NodeJS使用事件循环(作业队列)在单个线程上运行所有JavaScript代码,这是强烈鼓励使用异步系统调用而不是同步函数的原因之一。
readFile
安排读取操作,然后在I / O层等待数据进入时让JavaScript线程发生其他事情;当数据可用时,节点的I / O层将为JavaScript线程排队任务,这最终会使您的readFile
回调被调用。
相比之下,readFileSync
支持一个单独的JavaScript线程,等待文件数据变得可用。由于只有一个线程,它可以阻止其他所有您的代码可能正在做的事情,包括其他readFileSync
次调用。
您的代码不需要使用readFileSync
(您几乎从不这样做);只需使用readFile
的回调:
const asyncFnWithSyncCode(filePath, next) {
// Load file
fs.readFile(filePath, function(err, file) {
if (err) {
// ...handle error...
// ...continue if appropriate:
next(err, null);
} else {
// ...use `file`...
// Continue to process file with async functions
// ...
next(null, processedFile);
}
});
}