我正在使用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