繁体   English   中英

Promise.all返回未定义

[英]Promise.all is returning undefined

当我异步映射数组时,Promise.all应该让函数等待,直到所有的诺言都得到解决。 但是,Promise.all显示为未定义。 这是我的代码。 请有人能告诉我我做错了吗? 谢谢。

router.get("/vehicle_reports/interior-pictures", auth, async (req, res) => {

  const fileKeysObj = await Report.findOne({ orderId: req.params.jobId }, {
    "vehicleInterior": 1
  })
  const fileKeysArray = fileKeysObj.interior
  console.log("fileKeysArray: ", fileKeysArray);

  //Retrieve the files from S3
  const files = fileKeysArray.map(async (item) => {
    const params = {
      Bucket: process.env.AWS_BUCKET_NAME,
      Key: item.fileKey
    }
    await s3.getObject(params, async (err, data) => {
      if (err) {
        throw new Error()
      }
      else {
        const base64Data = base64Arraybuffer.encode(data.Body)
        const contentType = data.ContentType
        const fileName = item.fileName
        return { base64Data, contentType, fileName }
      }
    })
  })
  console.log( files) //Pending promise
  await Promise.all(files) 
  console.log( files) //Undefined
  res.send(files) //Sends empty array
})

我希望人们不再炒作async / await await关键字旨在与Promises一起使用。 并非所有异步函数都返回promise。 许多API(例如S3)都使用回调。 此外,您可能期望返回多个/无限数据的体系结构(例如服务器侦听传入连接或读取流)不适合基本上是单发的Promise。 对于那些EventEmitters更合适。

async关键字不会将函数转换为Promise。 它的确返回了一个Promise,但是不能将基于回调的函数转换为可与await一起使用的Promises。 为此,您需要使用原始的Promise构造函数。 因此,获得诺言数组的正确方法如下:

const files = fileKeysArray.map((item) => { /* note: async keyword is useless here */
  const params = {
    Bucket: process.env.AWS_BUCKET_NAME,
    Key: item.fileKey
  }


  // We are returning a Promise, so no need to force it to further
  // return a promise by marking this function as "async" above:

  return new Promise((perfectly_fine, oops_something_went_wrong) => {
    s3.getObject(params, async (err, data) => {
      if (err) {
        // Normally people would name this function "reject"
        // but I'm illustrating that the name is really up to you
        // and is not part of the syntax:

        oops_something_went_wrong(err)
      }
      else {
        const base64Data = base64Arraybuffer.encode(data.Body)
        const contentType = data.ContentType
        const fileName = item.fileName

        // This is how you "return" to a promise:

        perfectly_fine({ base64Data, contentType, fileName })
      }
    })
  })
})

现在您可以等待结果。 但是您使用的是await错误。 正确的await方式如下:

let resulting_files = await Promise.all(files);
console.log(resulting_files);

您也可以选择不使用等待。 相反,您可以使用.then()

Promise.all(files).then(resulting_files => {
  // use resulting_files here:

  console.log(resulting_files);
});

替换map调用的内部,如下所示。

const params = {
  Bucket: process.env.AWS_BUCKET_NAME,
  Key: item.fileKey
}
return new Promise((res, rej) => {
    s3.getObject(params, async (err, data) => {
      if (err) {
        rej('FAILED');
      } else {
        const base64Data = base64Arraybuffer.encode(data.Body)
        const contentType = data.ContentType
        const fileName = item.fileName
        res( { base64Data, contentType, fileName });
      }
    })

});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM