Javascript Nodejs在循环中下载s3图像(getObject)

Javascript Nodejs在循环中下载s3图像(getObject),javascript,node.js,amazon-s3,Javascript,Node.js,Amazon S3,我试图以循环的方式从S3 bucket下载图像。我的bucket不是公共的,使用直接getSignedURL不起作用(禁止的错误)。我需要在用户从用户界面选择后从S3下载(10-30)个图像(然后在创建GIF后删除) 它下载正确数量的图像(具有正确的名称),但所有图像的内容将替换为本地计算机上的最后一个图像。我甚至写了一个在循环中调用的承诺(希望每个getObject调用在进入下一个之前先完成),但没有成功。除了蓝鸟,我尝试了所有的解决方案,但结果相同。我的代码如下所示: var urlPara

我试图以循环的方式从S3 bucket下载图像。我的bucket不是公共的,使用直接getSignedURL不起作用(禁止的错误)。我需要在用户从用户界面选择后从S3下载(10-30)个图像(然后在创建GIF后删除)

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

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

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

按照@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");
    })
  }

您应该使用
let
而不是
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);
        } 
      });
    })
}
for(变量i=0;i{
让pathToSave='/local files/'+params.Key;
让tempFile=fs.createWriteStream(路径保存);
让stream=s3.getObject(params.createReadStream().pipe(tempFile);
let had_error=false;
stream.on('error',函数(err){
had_error=true;
});
stream.on('close',function(){
如果(!有错误){
解析(路径保存);
} 
});
})
}

首先解决您的身份验证问题。我没有在上面添加身份验证代码,但身份验证似乎工作正常。我不知道你指的是哪一行(部分)?我将所有内容(从循环内部)放在一个单独的函数中,然后在setTimeout中调用该函数本身,这似乎可行,但似乎不是一个好的解决方案。任何其他(更好的)建议都会很有帮助。我不知道该告诉你什么。如果你收到一个禁止的错误,并且你确定你的内容存在,那么你没有正确设置你的密钥/密码进行身份验证。哦,我明白了,很抱歉。内容确实存在,我进行了三次检查。我试图将图像(从signedURL)传递到另一个插件来读取它们并创建GIF,但它一直抛出禁止的错误。然后我在aws上添加了CORS配置,但后来我发现使用该插件直接从aws读取的图像不起作用(老实说,我没有对此进行太多调查),然后我决定先下载图像,然后在创建GIF后删除它们。您可以尝试使用
let
而不是
var
?特别是
var pathToSave='/local files/'+params.Key
将其更改为
let pathToSave='/local files/'+params.Key好的,谢谢,我刚刚投票表决了解决方案,但由于我的声誉,它只记录了,而没有公开显示
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);
        } 
      });
    })
}
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);
        } 
      });
    })
}