Nodejs 循环下载 s3 映像 (getObject)



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

它会下载正确数量的图像(具有正确的名称),但所有图像的内容将替换为本地计算机上的最后一个图像。我什至写了一个 Promise 在循环中调用(希望每个 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");        
} 
});    
}

上面的代码完成后,正如我提到的,所有具有正确名称的图像都会被保存,但由于这里的非阻塞问题,所有图像都包含数组中最后一个图像的内容(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);
} 
});
})
}

设置超时和承诺都不适用于我的问题。任何帮助将不胜感激。谢谢

你应该使用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);
} 
});
})
}

按照Jaiswal @Anshuman在评论中的建议,我尝试了使用 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);
} 
});
})
}

最新更新