同步函数在异步函数中的影响

时间:2016-04-17 15:19:35

标签: javascript node.js asynchronous callback

让我们想象一个异步函数,它首先加载一个文件,然后再与它进行异步处理。该函数无法在没有文件的情况下继续,因此我的假设是加载此文件可以同步完成(*):

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 - 版本,但我真的想知道它在这种特殊结构中是如何工作的。

1 个答案:

答案 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);
        }
    });
}