Node.js 流中“数据完全消耗”是什么意思?

问题描述 投票:0回答:1

背景

前一段时间,我问过这个问题一般可能是什么原因导致

on("end")
在Gulp管道中没有调用处理程序?。通过复制粘贴 Node.js 文档的 1 段内容,只有 1 个答案。当然,这还不足以穷尽问题,但回答者还没有用澄清问题来回答我的评论。

理想情况下,我想删除上一个问题,但我不能,因为它有已授予的答案。上一个问题的编辑不会吸引新的答案,所以我被迫提出新的答案。请让我重复一下“实验数据”部分中上一个问题的部分。

实验数据

下面不是工作示例,但是如果要简化我的基于Gulp的标记源代码linter类(目前大约有750行),它将是:

import type { TransformCallback } from "stream";
import Stream from "stream";
import VinylFile from "vinyl";


class MarkupSourceCodeLinter {
 
  public static provideLintingIfMust(
    projectBuildingMasterConfigRepresentative: ProjectBuildingMasterConfigRepresentative
  ): () => NodeJS.ReadWriteStream {

    const dataHoldingSelfSoleInstance: MarkupSourceCodeLinter = new MarkupSourceCodeLinter(/* */);

    // ...

    /* First run */
    return dataHoldingSelfSoleInstance.lint(dataHoldingSelfSoleInstance.targetFilesGlobSelectors);

  }


  protected lint(globSelectorsOrAbsolutePathsOfTargetFiles: Array<string>): () => NodeJS.ReadWriteStream {


    return (): NodeJS.ReadWriteStream => Gulp.

        src(globSelectorsOrAbsolutePathsOfTargetFiles, { read: false }).
                
                // ...
                
                pipe(new Stream.Transform({
                    objectMode: true,
                    transform(chunk: unknown, _encoding: BufferEncoding, callback: TransformCallback): void {
                        
                        console.log("CHECKPOINT1");
                        
                        if (chunk instanceof VinylFile) {
                            if (VinylFile.isVinyl(chunk)) {
                                console.log(chunk.path);
                            }
                        }
                        
                        callback(null, chunk);
                        
                    }
                })).

                on("end", (): void => {
                    console.log("CHECKPOINT2");
                });

  }
    
    private onMarkupSourceFileHasBeenAddedOrUpdated(targetMarkupFileAbsolutePath: string): void {

        //
        this.lint([ targetMarkupFileAbsolutePath ])();
    
  }

}

lint()
被外部调用时(通过 public static
provideLintingIfMust
),
on("end", () => {})
处理程序被调用。 然而,当从
lint()
调用
onMarkupSourceFileHasBeenAddedOrUpdated
时,检查点
console.log("CHECKPOINT1");
到达 但是
console.log("CHECKPOINT2");
- 不。只有一个文件发生了变化;预计不会有后续文件。

我想,我只是不知道

on("end", () => {})
何时被实际调用。

后续运行的控制台输出示例:

CHECKPOINT1
D:\XXX\FunctionalTests\MarkupProcessing\IncrementalBuilding\01-Source\Com
ponents\Header.pug

正好处理了一个文件,但

on("end", () => {})
尚未被调用。 一般可能是什么原因?

Node.js 文档阅读报告

我已阅读 Node.js 文档,该文档已复制粘贴到上一个问题的答案中。

事件:'结束'#

当没有更多数据可供消耗时,会发出“end”事件 来自流。

除非数据完整,否则不会发出 'end' 事件 消耗了。这可以通过将流切换到 流动模式,或者通过重复调用stream.read()直到所有数据 已被消耗。

Node.js 流 文档

不幸的是,它只是产生了新问题。

  1. “数据完全消耗”是什么意思?在随后的运行中,

    globSelectorsOrAbsolutePathsOfTargetFiles
    只是单个 glob 的数组(换句话说,是更改的文件的绝对路径)。所以,“数据被完全消耗”并不意味着“所有文件都已通过
    Gulp.src()

  2. “这可以完成..”中的“这”是什么意思?它指的是“不会发出‘结束’事件”或“数据被完全消耗”?

  3. “完成”是什么意思?我必须“完成”它本身就会“完成”吗?

  4. stream.read()
    与Gulp流有什么关系?

另外,可能是我查得不好,在 Node.js 文档中并没有找到关于“流动模式”的解释。我现在所知道的是流动模式,数据是自动从底层系统读取的(source),但也许这不是我所需要的。就我而言,

Gulp.src()
是从
onMarkupSourceFileHasBeenAddedOrUpdated
调用的 - 这是否意味着“自动”?

node.js gulp
1个回答
1
投票

我可以帮助解决 Nodejs 流的问题,但对 Gulp 的问题没有太多帮助。因此,我将尝试回答您的通用流问题。

Node.js 流中“数据被完全消耗”是什么意思?

对于 NodeJS 可读流,当向流提供数据的人告诉流已完成向流添加数据并且流的读取器已获得流的所有数据时,数据就被完全消耗了。对于不处于对象模式的流,通常由向流提供数据的任何代理使用

readable.push(null)
来完成。例如,对于可读文件流(就像您使用
fs.createReadStream()
得到的那样,当它到达正在读取的文件末尾时,它将指示流上的数据结束。

还可以调用

readable.destroy(err)
(其中
err
是可选的)以使可读设备停止发送更多数据。

“这可以完成..”中的“这”是什么意思?它指的是“不会发出‘结束’事件”或“数据被完全消耗”?

在该上下文中,“This”是“导致流发出

end

 事件”。它的基本意思是,有两种方法可以使用读取流中的所有数据。第一种是将其置于流动模式通过为 
data
 事件注册事件处理程序,例如 

stream.on('data', data => { process data here });
或者,如果流不处于流动模式(没有 

data

 事件侦听器),那么您可以重复从流中读取数据,直到耗尽可用数据并发出 
end
 事件。

“完成”是什么意思?我必须“完成”它本身就会“完成”吗?

“已完成”意味着您导致了

end

 事件的发出。

© www.soinside.com 2019 - 2024. All rights reserved.