在节点流管道链内运行函数一次



我正在使用vinyl-fs编写一个简单的管道,该管道加载降价文件,将其转换为HTML,并将其保存到磁盘。这一切都在起作用。

但是,在我的pipe()链的中间,我想执行一个异步任务,该任务应该只为我的所有文件执行一次。我目前的问题与加载文件有关(重要的是,将文件加载到链的中间),但我发现自己总是遇到这个问题。

为了解决这个问题,我已经开始这样做:

vfs.src(*.md).pipe(function() {
  var loaded = false;
  return through2.obj(function(file, enc, cb) {
    if(!loaded) {
      fs.readFile('myfile', function(err, data) {
        // use data for something
        loaded = true;
        cb(null, file);
      }
    } else {
      // passthrough
      cb(null, file);
    }
  });
}

这感觉有点傻。我是不是完全错了,或者这真的是一件可以做的事情?

在阅读了大量关于Node流的文章后,似乎最好的实现是侦听流finish事件,然后根据前一个流中的文件创建一个新的流。这让我可以做我想要做的事情:通过管道流式传输文件,直到我需要访问某个任务的文件数组,然后继续管道流。

以下是它的样子:

var vfs = require('vinyl-fs');
var through = require('through2');
// array for storing file objects
var files = [];
// start the stream
var firstStream = vfs.src("*.jpg")
  // pipe it through a function that saves each file to the array
  .pipe(through.obj(function(file, enc, cb) {
    files.push(file);
    console.log('1: ', path.basename(file.path));
    cb(null, file);
  }))
  // when this stream is done
  .on('finish', function() {
    console.log('FINISH');
    // files will now be full of all files from stream
    // and you can do whatever you want with them.        
    // create a new stream
    var secondStream = through.obj();
    // write the files to the new stream
    files.each(function(file) {
      secondStream.write(file);
    });
    // end the stream to make sure the finish
    // event triggers
    secondStream.end();
    // now continue piping
    secondStream.pipe(through.obj(function(file, enc, cb) {
      console.log('2: ', path.basename(file.path));
      cb(null, file)
    }))
    .pipe(vfs.dest("tmp"));
  });

在这个场景中,我的脚本旁边有5个JPG图像,console.log会显示

1:  IMG_1.JPG
1:  IMG_2.JPG
1:  IMG_3.JPG
1:  IMG_4.JPG
1:  IMG_5.JPG
FINISH
2:  IMG_1.JPG
2:  IMG_2.JPG
2:  IMG_3.JPG
2:  IMG_4.JPG
2:  IMG_5.JPG

相关内容

  • 没有找到相关文章

最新更新