2016-12-02 1 views
1

Ich möchte Ihnen zuerst einen Hintergrund geben.Wie eine Funktion ausgelöst wird, nachdem alle Downloads fertig sind

Ich habe eine Reihe von Bildparametern wie folgt:

"imageParameters": [ 
     { 
     "imageparam1": "param1", 
     "imageparam2": "param2", 
     "imageparam3": "param3" 
     }, 

     { 
     "imageparam1": "param1", 
     "imageparam2": "param2", 
     "imageparam3": "param3" 
     } 
    ] 

I Schleife durch diese eindeutige URLs pro Bild zu erzeugen. Dann lösen Sie die downloadImageAndSave-Funktion jedes Mal aus, wenn URL generiert wird.

imageParameters.forEach(function (image) { 
var imageUrL = baseURL + "&param1=" + image.imageparam1 + "&param2=" + image.imageparam2 + "&param3=" + image.imageparam3 ; 

var imageparam1 = image.imageparam1; 
downloadImageAndSave(imageUrL, imageparam1); 

    }); 

function downloadImageAndSave(imageUrL, imageparam1) { 

    console.log("Download function is triggered") 
    var fs = require('fs'), 
     request = require('request'); 

    request 
     .get(imageUrL) 
     .on('error', function(err) { 
      // handle error 
     }) 
     .pipe(fs.createWriteStream('./imagesLocation/' + imageparam1 + '.jpeg')); 

myfunctionTobeTRiggeredAfterImagesDownloadedAndSaved(); 
} 

Woher weiß ich, dass alle diese Bilder heruntergeladen und gespeichert werden, damit ich meine Funktion auslösen kann?

Das Problem, das ich habe, ist, den Rückruf zu verwenden. Ich kann nicht zurückrufen, sobald alle Bilder heruntergeladen und gespeichert sind.

Jede Hilfe würde sehr geschätzt werden. Danke.

AKTUALISIERT

Unten ist der Workflow ich zu erreichen versuchen. Ich bekomme eine Eingabe vom Benutzer per Express API wie folgt.

Dann geben Sie die gezippte Datei, die die Bilder enthält, an den Benutzer zurück.

function returnTheZipFileToUser(id) { 

    var path = require('path'); 
    var mime = require('mime'); 
    var file = __dirname + '/public/imagelocation/' + id + '.zip'; 
    var filename = path.basename(file); 
    var mimetype = mime.lookup(file); 

    res.setHeader('Content-disposition', 'attachment; filename=' + filename); 
    res.setHeader('Content-type', mimetype); 

    var filestream = fs.createReadStream(file); 
    filestream.pipe(res); 
} 

Der returnTheZipFileToUser wird zu früh aufgerufen, bevor die Bilder heruntergeladen und gezippt werden. Daher bekomme ich das image.zip Datei nicht gefunden Problem, da es viel zu früh vor dem zipImageFiles() und downloadImagesToNodeServer ausgelöst wird.

Ich fand einen hacky Weg, um das setTimeout zu implementieren, um zu warten, bis die Downloads fertig sind, und dann die returnTheZipFileToUser (ID) auszulösen. Dies ist jedoch keine echte Lösung, da das Timing abhängig von der Größe der Bilder und der Zip-Datei unterschiedlich ist. Also ich brauche eine todsichere Möglichkeit, dass die Bilder vollständig heruntergeladen werden und gezippte Datei bereit ist, bevor die returnTheZipFileToUser aufgerufen wird.

+0

Bitte formatieren Sie den Code entsprechend. – jfriend00

Antwort

2

Wenn Sie den Strom aus downloadImageAndSave zurückkehren, könnte man dann so etwas wie stream-concat verwenden alle Ströme in einen einzigen Strom verketten, die Sie für das Finish Ereignis hören konnte:

function downloadImages(imageParameters, cb) { 

    var streams = imageParameters.map(function (image) { 
    var imageUrL = baseURL + "&param1=" + image.imageparam1 + "&param2=" + image.imageparam2 + "&param3=" + image.imageparam3 ; 

    var imageparam1 = image.imageparam1; 
    return downloadImageAndSave(imageUrL, imageparam1); 
    }); 

    var combinedStream = new StreamConcat(streams); 
    combinedStream.on('error', function(error) { 
    cb(error); 
    }); 
    combinedStream.on('finish', function() { 
    cb(); 
    }); 
} 

function downloadImageAndSave(imageUrL, imageparam1) { 

    console.log("Download function is triggered") 
    var fs = require('fs'), 
     request = require('request'); 

    return request 
     .get(imageUrL) 
     .on('error', function(err) { 
      // handle error 
     }) 
     .pipe(fs.createWriteStream('./imagesLocation/' + imageparam1 + '.jpeg')); 
} 
+0

Vielen Dank dafür. Ich bin mir nicht sicher, wo die Callback-Funktion in diesem –

+0

Hallo pgreen2 definiert ist, ich kämpfe immer noch mit diesem. Ich habe 2 Funktionen, die ich nach dem Herunterladen der Bilder auslösen muss. 1- Zip die Bilder in einen Ordner 2- Kopieren Zip-Datei an einen anderen Speicherort. Ich habe diese Funktionen unter combined.stream.on ('Ende'). Es löst nur die Funktionen nicht aus. Weißt du, was das verursacht? –

+0

"Ende" sollte für jeden Stream aufgerufen werden, außer wenn ein Fehler aufgetreten ist. Behandeln Sie das Fehlerereignis? – pgreen2

Verwandte Themen