我正在使用vinyl-fs
编写一个简单的管道来加载markdown文件,将它们转换为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);
}
});
}
这感觉有点傻。我接近这一切都错了,或者这实际上是一件好事吗?
答案 0 :(得分:0)
在阅读了大量关于节点流的文章后,似乎最好的实现方法是监听流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