You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gulp流水线中on("end")回调未触发的常见原因

Gulp流水线中on("end")回调未触发的通用排查原因

场景说明:通过静态方法provideLintingIfMust调用lint()时,on("end")回调可正常触发;但在onMarkupSourceFileHasBeenAddedOrUpdated中处理单个文件时,仅能触发CHECKPOINT1,无法触发CHECKPOINT2。

以下是该情况的通用排查原因:

  • 流未被正确消费:Gulp基于Node.js Stream实现,只有流被完全消费(比如后续接dest()、pipe()到其他处理,或手动调用resume()),才会触发end事件。若仅创建流无后续消费操作,流可能处于暂停状态,无法走完整个生命周期。
  • 单个文件的流未完成数据推送:处理单个文件时,若文件路径存在权限问题、文件已被删除等情况,gulp.src可能提前终止流但未发出end信号;或文件读取过程中出现未捕获的异常,导致流无法正常结束。
  • 自定义Transform流存在阻塞:自定义的Transform流中,若transform方法里某些分支未调用callback,或callback调用异常,会阻塞流的推进,导致end事件无法触发。
  • 流的实例或作用域异常:在onMarkupSourceFileHasBeenAddedOrUpdated中创建的流,可能因作用域冲突、实例重复创建或内部状态异常,导致end事件监听未正确绑定,或流的生命周期被意外中断。
  • Gulp配置或版本差异:不同版本的Gulp对src的处理逻辑有差异,比如{ read: false }配置在处理单个文件时,可能影响end信号的发送逻辑;部分版本中空流或单个文件流的end事件触发逻辑与多文件场景不同。
  • 异步操作未正确处理:若lint方法或流处理链中存在未被正确等待的异步操作,可能导致流在异步任务完成前就尝试触发end,但实际流还未处理完毕。

简化代码示例

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 ])();
    
  }

}

内容的提问来源于stack exchange,提问作者Takeshi Tokugawa YD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 00:14:53