更新 forEach 数组时,AWS SDK S3 在 forEach 内调用

AWS SDK S3 calls, inside a forEach while updating the forEach array

首先,我使用 s3.listObject() 方法获取存储桶中的对象列表。这是一个承诺,我将结果发送到另一个函数,我想在其中循环遍历结果并收集每个对象的元数据:

  S3.listObjects({
    Bucket: bucketName,
    MaxKeys: 10,
    Marker: marker,
  })
  .promise()
  .then(collectRedirects)
  .then(callback); // each object in my list should now all have a new property, the metatag

在 collectRedirects 函数中,我需要遍历传入的结果,然后使用另一个异步函数 s3.getObject 来获取元标记。类似于:

collectRedirects(objects) {
    objects.forEach(function(e,i,a){
        a[i].foo = S3.getObject({
            Key: e.Key,
            Bucket: bucketName
          })
          .promise()
          .then(function(result){
            Promise.resolve( result.foo );
          });
      }); //end loop
   return objects;
}

但是循环在 getObject 方法解析之前完成。我的下一步是什么?

我试图将 getObject 方法的结果保存到一个 promises 数组,然后 运行 Promise.all,但这只是给我一个未定义值的数组:

var promises = [];
objects.forEach(function(e,i,a){
  let p = S3.getObject({...})
  .promise().then(function(result){ 
    Promise.resolve( result.foo ); 
  });
  promises.push(p);
});
Promise.all(promises)
.then(function(values) {
  console.log(values);
});

我应该怎么做?

你的问题是你没有returnfunction(result){ Promise.resolve( result.foo ); }中获取任何东西。它只是创建一个 promise,然后删除它并且 returns undefined.

您正在寻找 function (result) { return result.foo; }.

总而言之,你会写

collectRedirects(objects) {
  var promises = objects.map(function(e){
    return S3.getObject({
      Key: e.Key,
      Bucket: bucketName
    }).promise().then(function(result){
      return result.foo;
      // or alternatively (if you want to amend the original object)
      e.foo = result.foo;
      return e;
    });
  });
  return Promise.all(promises).then(function(values) {
    console.log(values);
    return values;
  });
}