所有下载完成后如何触发一个function

我想先给你一个背景。

我有一个像下面的图像参数数组:

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

我通过循环来生成每个图像独特的url。 然后在每次生成url时触发downloadImageAndSave函数。

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

我怎么知道所有这些图像下载和保存,以便我可以触发我的function?

我遇到的问题是使用callback。 一旦所有的图像下载并保存,我不是如何得到callback。

任何帮助将非常感激。 谢谢。

更新

以下是我想要实现的工作stream程。 我通过这样的快速API从用户那里得到一个input。

  app.get('/getStudyID', function(req, res) { var id = req.query['getStudyID']; //pass this to a variable to be used by various functions. downloadImagesToNodeServer(id); zipImageFiles(); returnTheZipFileBackToUser(id); } 

然后将包含图像的压缩文件返回给用户。

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

图像下载和压缩之前,过早调用returnTheZipFileToUser。 因此,我得到image.zip文件没有find问题,因为它是在zipImageFiles()和downloadImagesToNodeServer之前触发的方式太早。

我发现一个黑客的方式来实现setTimeout等待下载完成,然后触发returnTheZipFileToUser(id)。 但这不是一个真正的解决scheme,因为时间根据图像和zip文件的大小而不同。 所以我需要一个绝对的方式,图像被完全下载和压缩文件准备就绪之前returnTheZipFileToUser被调用。

如果您从downloadImageAndSave返回stream,则可以使用类似stream-concat的方式将所有stream串接到一个可以监听结束事件的stream中:

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