完成所有下载后如何触发功能

时间:2016-12-02 03:33:31

标签: node.js

我想先给你一个背景。

我有一系列图像参数,如下所示:

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

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

我遍历这个以生成每个图像的唯一网址。 然后在每次生成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();
}

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

我遇到的问题是使用回调。一旦下载并保存了所有图像,我就无法获得回调。

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

已更新

以下是我想要实现的工作流程。 我通过Express 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)的hacky方法。但这不是一个真正的解决方案,因为时间根据图像和zip文件的大小而有所不同。 因此,在调用returnTheZipFileToUser之前,我需要一种完全下载图像并且压缩文件准备就绪的万无一失的方法。

1 个答案:

答案 0 :(得分:2)

如果您从downloadImageAndSave返回流,则可以使用stream-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'));
}