简体   繁体   English

createreadstream是异步的吗?

[英]Is createreadstream asynchronous?

https://nodejs.org/api/fs.html#fs_fs_createreadstream_path_options . https://nodejs.org/api/fs.html#fs_fs_createreadstream_path_options I also have a general question . 我也有一个普遍的问题。

Can I assume that unless otherwise stated in the documentation , any function mentioned is asynchronous? 我可以假设,除非文档中另有说明,否则提到的任何功能都是异步的?

Is createreadstream asynchronous? createreadstream是异步的吗?

Yes and no. 是的,不是。 This question is really more a matter of semantics than anything because it hides an asynchronous operation under a synchronous looking interface. 这个问题实际上比语义更重要,因为它隐藏了同步外观下的异步操作。 fs.createReadStream() appears to have a synchronous interface. fs.createReadStream()似乎有一个同步接口。 It does not return a promise or accept a callback to communicate back when it's done or to send back some results. 它不会返回承诺或接受回调,以便在完成后回传或发回一些结果。 So, it appears synchronous from the interface. 因此,它从界面看起来是同步的。 And, we know from using it that there's nothing you have to wait for in order to start using the stream. 并且,我们从使用它知道,为了开始使用流,您无需等待。 So, you use it as if it was a synchronous interface. 所以,你使用它就好像它是一个同步接口。

Here's the signature for fs.createReadStream() : 这是fs.createReadStream()的签名:

fs.createReadStream(path[, options])

And, in the options object, there is no callback option and no mention of a returned promise. 而且,在options对象中,没有回调选项,也没有提到返回的promise。 This is not a typical asynchronous interface. 这不是典型的异步接口。


On the other hand if you look at the signature of fs.rename() : 另一方面,如果你看一下fs.rename()的签名:

fs.rename(oldPath, newPath, callback)

You see that it takes a callback that is referred to in the doc as the "completion callback". 您会看到它需要在文档中引用的回调作为“完成回调”。 This function is clearly asynchronous. 这个功能显然是异步的。


But, fs.createReadStream() does open a file and it opens that file asynchronously without blocking. 但是, fs.createReadStream()会打开一个文件,它会异步打开该文件而不会阻塞。

If you're wondering how fs.createReadStream() can be synchronous when it has to open a file asynchronously, that's because fs.createReadStream() has not yet opened the file when it returns. 如果你想知道fs.createReadStream()在必须异步打开文件时是如何同步的,那是因为fs.createReadStream()在返回时还没有打开文件。

In normal use of the stream, you can just start reading from the stream immediately. 在正常使用流时,您可以立即开始从流中读取。 But, internally to the stream, if the file is not yet opened, it will wait until the file is done being opened before actually attempting to read from it. 但是,在流内部,如果文件尚未打开,它将等到文件完成打开,然后才真正尝试从中读取。 So, the process of opening the file is being hidden from the user of the stream (which is generally a good thing). 因此,打开文件的过程对流的用户是隐藏的(这通常是一件好事)。

If you wanted to know when the file as actually done being opened, there is an open event on the stream. 如果您想知道文件实际open时间,则流上有一个open事件。 And, if there's an error opening the file, there will be an error event on the stream. 并且,如果打开文件时error ,则流上会出现error事件。 So, if you want to get technical, you can say that fs.readStream() actually is an asynchronous operation and completion of the async operation is communicated via the open or error events. 所以,如果你想获得技术,你可以说fs.readStream()实际上是一个异步操作,异步操作的完成是通过openerror事件传递的。

let rstream = fs.createReadStream("temp.txt");
rstream.on('open', (fd) => {
    // file opened now
});
rstream.on('error', (err) => {
    // error on the stream
});

But, in normal usage of fs.createReadStream() , the programmer does not have to monitor the file open event because it is hidden from the user and handled automatically when the stream is read from next. 但是,在fs.createReadStream()正常使用中,程序员不必监视文件打开事件,因为它对用户是隐藏的,并且在从下一个读取流时自动处理。 When you create a read stream and immediately ask to read from it (which is an asynchronous interface), internally the stream object waits for the file to finish opening, then reads some bytes form it, waits for the file read to finish and then notifies completion of the read operation. 当你创建一个读取流并立即要求从它读取(这是一个异步接口)时,流对象内部等待文件完成打开,然后从中读取一些字节,等待文件读取完成然后通知完成读操作。 So, they just combine the file open completion with the first read, saving the programmer an extra step of waiting for the file open to finish before issuing their first read operation. 因此,他们只是将文件打开完成与第一次读取相结合,为程序员节省了额外的步骤,即在发出第一次读取操作之前等待文件打开完成。

So, technically fs.createReadStream() is an asynchronous operation that has completion events. 因此,技术上fs.createReadStream()是一个具有完成事件的异步操作。 But, because of the way it's been combined with reading from the file, you don't generally have to use it like it's asynchronous because it's asynchronous behavior is combined with the async reading from the file. 但是,由于它与从文件读取相结合的方式,你通常不必像使用异步一样使用它,因为它的异步行为与来自文件的异步读取相结合。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM