后台
前一段时间,我问了What generally could be the cause of on("end")
handler has not been called in Gulp pipeline?这个问题。只有一个答案,复制粘贴了Node.js文档的一段。当然,这是不够的,用尽的问题,但回答者没有回答我的评论与澄清的问题。
理想情况下,我想删除前一个问题,但我不能,因为它有奖励的答案。上一个问题的编辑不会吸引新的答案,所以我被迫问新的。请让我重复一下上一个问题中“实验数据”部分的内容。
实验数据
下面不是工作示例,但如果要简化我基于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()
被外部调用时(通过公共静态provideLintingIfMust
),on("end", () => {})
处理程序被调用。但是,当从onMarkupSourceFileHasBeenAddedOrUpdated
调用lint()
时,检查点console.log("CHECKPOINT1");
到达,但console.log("CHECKPOINT2");
-no。只有一个文件已更改;不期望后续文件。
我想,我只是不知道什么时候on("end", () => {})
被真正调用。
后续运行时的控制台输出示例:
CHECKPOINT1
D:\XXX\FunctionalTests\MarkupProcessing\IncrementalBuilding\01-Source\Com
ponents\Header.pug
只处理了一个文件,但没有调用on("end", () => {})
。一般可能是什么原因?
Node.js文档阅读报告
我已经阅读了Node.js文档,该文档已被复制粘贴在上一个问题的答案中。
事件:'end'#
当流中没有更多的数据要使用时,会发出“end”事件。
除非数据被完全消耗,否则不会发出“end”事件。这可以通过将流切换到流动模式来实现,或者通过反复调用stream.read()直到所有数据都被消耗。
Node.js Stream文档
不幸的是,它只是催生了新的问题。
1.什么是“数据被完全消耗”?在随后的运行中,globSelectorsOrAbsolutePathsOfTargetFiles
只是单个globs的数组(换句话说,就是更改文件的绝对路径)。因此,“数据完全消耗”并不意味着“所有文件都已通过Gulp.src()
。
1.“这是可以实现的”中的“这”是什么意思?它指的是“不会发出‘end’事件”或“数据已完全消耗”?
1.“完成”是什么意思它将是“完成”本身的我必须“完成”吗?
stream.read()
与Gulp流有什么关系?
另外,可能我没有好好搜索,在Node.js文档中没有找到关于“流模式”的解释。我现在所知道的是在流动模式下,数据是自动从底层系统读取的(source),但也许这不是我所需要的。在我的例子中,Gulp.src()
是从onMarkupSourceFileHasBeenAddedOrUpdated
调用的-这是否意味着“自动”?
1条答案
按热度按时间slsn1g291#
我可以帮助nodejs流的东西,而不是那么多的Gulp的东西。因此,我将尝试回答您的一般流问题。
在Node.js流中,“数据被完全消耗”是什么意思?
对于节点可读的流,当向流提供数据的人已经告诉流它已经完成向流添加数据并且流的读取器已经被给予流的所有数据时,数据被完全消耗。对于流,而不是对象模式,通常由向流提供数据的任何代理使用
readable.push(null)
完成。例如,对于可读文件流(就像您使用fs.createReadStream()
所获得的那样),当它到达正在阅读的文件的末尾时,它将指示流上数据的末尾。也可以调用
readable.destroy(err)
(其中err
是可选的)来使可读的停止发送更多的数据。“这是可以实现的”中的“这”是什么意思?它指的是“不会发出‘end’事件”或“数据已完全消耗”?
在那个上下文中,“这”是“导致流发出
end
事件。它基本上是说,有两种方法可以使用读流中的所有数据。第一种方法是将其置于流模式,通常通过注册data
事件的事件处理程序,例如或者,如果流没有处于流动模式(没有
data
事件侦听器),那么您可以重复从流中读取,直到耗尽可用数据并发出end
事件。“完成”是什么意思它将是“完成”本身的我必须“完成”吗?
“已完成”意味着您引发了
end
事件。