Nodejs循环下载s3图像(getObject)

时间:2018-04-13 04:37:27

标签: javascript node.js amazon-s3

我正在尝试从循环中的S3存储桶下载图像。我的存储桶不公开,使用直接getSignedURL不起作用(禁止错误)。我需要在用户选择用户界面时从S3下载(10-30之间)图像(然后在创建GIF后删除)。

下载正确数量的图像(名称正确),但所有图像的内容将替换为本地计算机上的最后一张图像。我甚至写了一个Promise来调用循环(希望每个getObject调用在转到下一个之前先完成)但是没有用。除了蓝鸟,我尝试了this的所有解决方案,但结果相同。我的代码如下所示:

var urlParams = {Bucket: 'bucket_name', Key: ''};
  for (i = 0; i < imageNames.length; i+=increment) {
    urlParams.Key = imageNames[i]+'.jpg';
    pathToSave = '/local-files/'+urlParams.Key;

    var tempFile = fs.createWriteStream(pathToSave);
    // I tried a Promise (and setTimeout) here too but gives me the same result
    var stream = s3.getObject(urlParams).createReadStream().pipe(tempFile);
    var had_error = false;
    stream.on('error', function(err){
      had_error = true;
    });
    stream.on('close', function(){
      if (!had_error) {
        console.log("Image saved");        
      } 
    });    
  }

在上面的代码完成后,正如我所提到的,保存了所有具有正确名称的图像,但由于此处存在非阻塞问题,所有图像都包含数组中最后一个图像的内容(imageNames)。我编写并尝试过的承诺是

function getBucketObject(urlParams){
    return  new Promise ((resolve, reject)=> { 
      var pathToSave = '/local-files/'+params.Key;
      var tempFile = fs.createWriteStream(pathToSave);
      var stream = s3.getObject(params).createReadStream().pipe(tempFile);
      var had_error = false;
      stream.on('error', function(err){
        had_error = true;
      });
      stream.on('close', function(){
        if (!had_error) {
          resolve(pathToSave);
        } 
      });
    })
}

setTimeout和Promise都不能解决我的问题。任何帮助将不胜感激。感谢

2 个答案:

答案 0 :(得分:0)

按照@Anshuman Jaiswal在评论中提出的建议,我尝试使用let而不是var来实现代码,现在它可以工作了。谢谢安舒曼。循环中的代码如下所示

for (var i = 0; i < imageNames.length; i+=increment) {
    let urlParams = {Bucket: 'bucket_name', Key: imageNames[i]+'.jpg'};
    let pathToSave = '/local-files/'+urlParams.Key;
    getBucketObject(urlParams).then(function(pathToSave){
      console.log("image saved");
    })
  }

承诺功能在

之下
function getBucketObject(urlParams){
    return  new Promise ((resolve, reject)=> { 
      let pathToSave = '/local-files/'+params.Key;
      let tempFile = fs.createWriteStream(pathToSave);
      let stream = s3.getObject(params).createReadStream().pipe(tempFile);
      let had_error = false;
      stream.on('error', function(err){
        had_error = true;
      });
      stream.on('close', function(){
        if (!had_error) {
          resolve(pathToSave);
        } 
      });
    })
}

答案 1 :(得分:0)

您应该使用var代替for (var i = 0; i < imageNames.length; i+=increment) { let urlParams = {Bucket: 'bucket_name', Key: imageNames[i]+'.jpg'}; let pathToSave = 'img/analysis/'+urlParams.Key; getBucketObject(urlParams).then(function(pathToSave){ console.log("image saved"); }) } function getBucketObject(urlParams){ return new Promise ((resolve, reject)=> { let pathToSave = '/local-files/'+params.Key; let tempFile = fs.createWriteStream(pathToSave); let stream = s3.getObject(params).createReadStream().pipe(tempFile); let had_error = false; stream.on('error', function(err){ had_error = true; }); stream.on('close', function(){ if (!had_error) { resolve(pathToSave); } }); }) }

将您的代码修改为:

 def smesh():
   fin = []
   i = 0 
   numl= [9,8,3,2,1,2,3,4,3,2]
   r = numl.pop(0)
   r = r**11
   n = numl.pop(0)
   flis = numl[::2]
   numl.pop(0)
   slis = numl[::2]
   newl = list((zip(flis,slis)))
   for x,y in itertools.combinations(newl,2):
     p = (((x[0]-y[0])**2)+ ((x[1]-y[1])**2))
   if p<=r:
       fin.append([x,y])
   <---below here is my prob area--->
   for x,y in itertools.combinations(fin,2):
     if x[0] in y:
      fin.append(x+y)
     elif x[1] in y:
       fin.append(x+y)
   print(fin)