Node.js 为什么有些人会大口大口地喝溪水;“流动”;默认情况下,而其他人不这样做?

Node.js 为什么有些人会大口大口地喝溪水;“流动”;默认情况下,而其他人不这样做?,node.js,stream,pipe,gulp,Node.js,Stream,Pipe,Gulp,考虑以下两个吞咽任务: gulp.task('src', function(done) { gulp.src('docs/*') .on('end', function() { console.log('ending'); done(); }); }); gulp.task('dest', function(done) { gulp.src('docs/*') .pipe(gulp.dest('temp')) .on('end',

考虑以下两个吞咽任务:

gulp.task('src', function(done) {
  gulp.src('docs/*')
    .on('end', function() {
      console.log('ending');
      done();
    });
});

gulp.task('dest', function(done) {
  gulp.src('docs/*')
    .pipe(gulp.dest('temp'))
    .on('end', function() {
      console.log('ending');
      done();
    });
});
运行
gulp dest
的行为符合预期,输出:

[12:33:15] Using gulpfile ~/Projects/gulp-exit/gulpfile.js
[12:33:15] Starting 'dest'...
ending
[12:33:15] Finished 'dest' after 13 ms
但是,运行
gulp src
仅输出:

[12:31:11] Using gulpfile gulpfile.js
[12:31:11] Starting 'src'...
从不调用
'end'
回调。经过一点调试后,我认为
dest
任务中的流是,而源任务中的流不是

通过调用
stream.resume()
,显式通知
src
任务流动:

给出了预期的输出:

[12:46:52] Using gulpfile gulpfile.js
[12:46:52] Starting 'src'...
ending
[12:46:52] Finished 'src' after 11 ms
我在插件中看到了同样的行为组合:似乎返回流而不返回流


为什么行为上有差异

这不是原因的答案,但我整合了一个模块来在短期内消除这些怪癖:

end = require('stream-end')

gulp.task 'logger', (done) ->
  gulp.src 'docs/*'
    .pipe logger()
    .pipe end ->
      console.log('ending')
      done()

无论上游是否在流动,传递到end的回调都会被调用。

发生这种情况的原因是,有些流需要读取数据,而有些流没有

gulp.src('docs/*')
返回一个可读流,其中包含
docs
中每个文件的数据。
end
事件仅在从流中读取所有数据后触发可读流

通常情况下,您将通过管道将其传输到另一个自动执行此操作的流,但由于您不是,因此需要使用:

gulp.task('src', function(done) {
  gulp.src('docs/*')
    .on('data', function() {})
    .on('end', function() {
      console.log('ending');
      done();
    });
});
或者,您可以使用
finish
事件,该事件(我认为)等待所有数据被推送到流中(即,它完成工作):

您的第二个gulp任务使用
gulp.dest('temp')
,它返回一个没有数据的流,因此处理完流后会立即触发
end

gulp.task('src', function(done) {
  gulp.src('docs/*')
    .on('data', function() {})
    .on('end', function() {
      console.log('ending');
      done();
    });
});
gulp.task('src', function(done) {
  gulp.src('docs/*')
    .on('finish', function() {
      console.log('ending');
      done();
    });
});