2016-12-02 117 views
1

我想先给你一个背景。如何在所有下载完成后触发一个功能

我有图像参数的阵列就像下面:

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

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

通过此I循环来生成每个图像的唯一的网址。 然后在每次生成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(); 
} 

我如何知道所有这些图像被下载和保存,以便我可以触发我的功能?

我遇到的问题是使用回调。我不是如何一旦下载并保存所有图像就可以获得回调。

任何帮助将不胜感激。 谢谢。

修订

下面是我想达到的工作流程。 我通过这样的快速API从用户那里获得输入。

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文件没有找到问题,因为它在zipImageFiles()和downloadImagesToNodeServer之前触发的方式太早。

我发现了一个奇怪的方法来实现setTimeout等待下载完成,然后触发returnTheZipFileToUser(id)。但是这不是一个真正的解决方案,因为时间根据图像和zip文件的大小而不同。 因此,我需要一个绝对的方式,即在调用returnTheZipFileToUser之前完全下载图像并压缩文件。

+0

请相应地格式化你的代码。 – jfriend00

回答

2

如果从downloadImageAndSave返回流,然后你可以使用类似stream-concat所有流的Concat的到一个单一的数据流,你可以听,对于终点事件:

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

谢谢你。 我不确定这个 –

+0

中的回调函数是在哪里定义的,嗨pgreen2,我仍然在为这个而苦苦挣扎。 我有2个功能,我需要下载图像后触发。 1-将图像压缩到文件夹 2-将zip文件复制到其他位置。 我有combined.stream.on('完成')下的这些功能。它只是不触发功能。你知道这可能是什么原因吗?除非发生错误,否则应调用任何流的'完成' –

+0

。你在处理错误事件吗? – pgreen2

相关问题