2016-03-24 3 views
0

Ich verwende vinyl-fs, um eine einfache Pipeline zu schreiben, die Markdown-Dateien lädt, konvertiert sie in HTML und speichert sie auf der Festplatte. Das funktioniert alles.Running-Funktion einmal in Knoten Stream-Pipeline-Kette

Allerdings in der Mitte meiner pipe() Kette möchte ich eine asynchrone Aufgabe durchführen, die nur einmal für alle meine Dateien durchgeführt werden sollte. Mein derzeitiges Problem bezieht sich auf das Laden einer Datei (und es ist wichtig, dass die Datei in der Mitte der Kette geladen wird), aber es ist ein Problem, bei dem ich ständig stolpere.

Um dieses Problem zu lösen, habe ich begonnen, dies zu tun:

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); 
    } 
    }); 
} 

Das fühlt sich ein bisschen dumm. Komme ich das alles falsch an, oder ist das eigentlich eine gute Sache?

+0

sagen, es scheint ok aber Sie müssen global "loaded" deklarieren oder es wird nie funktionieren. – Shanoor

+0

Danke. Wäre es möglich, pause() und resume() zu verwenden, anstatt die Funktion through2.obj und den booleschen Zähler zu verwenden? – Ronze

+0

Ehrlich gesagt, ich weiß es nicht. – Shanoor

Antwort

0

Nach dem Lesen einer Tonne Artikel über Node-Streams scheint es, dass die beste Implementierung dafür ist, die Streams finish Ereignis zu hören, und dann einen neuen Stream basierend auf den Dateien aus dem ehemaligen Stream erstellen. Dadurch kann ich genau das tun, was ich möchte: Dateien durch die Pipeline streamen bis zu einem Punkt, wo ich auf das Array von Dateien für eine Aufgabe zugreifen muss, und dann den Pipeline-Stream danach fortsetzen.

Hier ist, wie das aussieht:

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")); 
    }); 

In diesem Szenario I 5 JPG-Bilder neben meine Skripte haben, und die console.log wird ohne das größere Bild

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 
Verwandte Themen