结束正在进行的 Gulp 流的正确方法是什么?

What is the correct way to end a Gulp stream in progress?

我正在将 G运行t 构建任务转换为 Gulp 实现。我正在使用 gulp-watch,这是我为 运行 我的任务编写的:

gulp.task('task', function(){
    return watch('glob/**/*', function(){
        var stream = doTask();
        return stream;
    })
});

问题是,如果更改了很多文件,任务 运行 次数太多了。我需要找到一种方法来消除输入的抖动,并取消在有新变化时已经开始的任何任务。

如何取消 Node.JS / Gulp 流?我一直无法找到关于此的良好文档。我目前正在尝试 .end(),但我不能保证 Gulp 任务(SASS、Autoprefixer 和 CleanCSS)会遵守这一点。

似乎 gulp watch debounce 和 interval 选项将只处理特定的文件,即如果同一文件被更改,则防止重复调用。我发现一个可行的解决方案是使用外部 lodash debounce:

watch(GLOB_expression, _.decounce(handler, delay));

或者具体来说,在您的情况下:

gulp.task('task', function(){
    return watch('glob/**/*', _.debounce(function(){
        var stream = doTask();
        return stream;
    }, 1000));
});    

lodash decounce 默认设置为在后沿触发,这意味着只要事件不断进来,它就会等待,并且只有在指定时间段(1000 ms in上面的示例),处理程序将被调用。

一些注意事项:

  1. 列表项 确保你安装了 npm 并需要 lodash。
  2. 在“;”中结束您的 return 语句:-)
  3. 选择一个适当的延迟,这样你的处理程序就会进入 'starvation',即永远不会因正在进行的事件而触发,或者包括 maxWait 选项以确保它在之后触发一个合理的时间(比如 3000 毫秒),不管传入事件如何。

我最后做的是制作一个小的 class 来缓冲流

https://gist.github.com/bryanerayner/cc2bb9b4da243d94f0f8

gulp 文件:

function setupQuickSassJob(sourceGlob, watchGlob) {
    function job() {

        function taskFactory() {
            return jobs.processSassStyles(
                    gulp.src([].concat(sourceGlob), { base: '.' }),
                    '.');
        }

        gUtil.log('Listening for changes');

        var queue = new StreamQueue();

        var watchtask = watch([].concat(watchGlob), function (file) {

            gUtil.log('Changed: ' + file.path);

            return queue.queueTask(taskFactory);
        });

        return watchtask;
    }
    return job;
}

gulp.task('desktopSASS', setupQuickSassJob([
    'Globs',
],
[
    'Globs'
    ]
));

我对此并不完全满意,但它确实有效。如果有人有更合适的 Node 方法来做到这一点,我洗耳恭听。