首页 > 解决方案 > 使用 JS Promise All 在 AWS S3 中获取多个对象 - Nodejs 和 Express

问题描述

我正在尝试通过循环从 AWS S3 获取多个图像但我​​无法从该循环返回多个图像数据

获取单个图像

const getImage = async (imgKay) => {
    let tempImage = null;
    if (imgKay !== "default-header.jpg") {
       tempImage = await s3.getObject({Key: imgKay, Bucket: process.env.AWS_BUCKET_NAME}).promise();
    }
    return tempImage;
}

通过循环获取多个对象

const loopAllImageAndAddToList = (blockContent) => {
    console.log("Data fetching please wait");
    let imgList = new Array();
    blockContent.forEach(async (bc, bcIdx, arrNum) => {
        console.log("index: " + bcIdx + " Array Length: ", arrNum.length);
        if (bc.blockElement.name === "imgBlockContent") {
            const tempImage = await getImage(bc.blockElement.imgUrl);
            imgList.push({ key: bc.blockElement.imgUrl, binaryImg: tempImage.Body });
        }
    });


    return Promise.all(imgList);
}

快速获取请求

router.get('/preview/:id', (req, res, next) => {
    const sql = `SELECT id, title, bg_img, bg_color, link_color, layout, content, sibling FROM nodejs_story WHERE id=?`;

    conn.query(sql, [req.params.id], async (err, result, fields) => {
        if (err) throw err;
        try {
            const blockContent = await JSON.parse(result[0].content);
            const res = await loopAllImageAndAddToList(blockContent)
                console.log("res: ", res);
            res.render('template/template-preview', { docs: result[0] });
        } catch (readFileErr) {
            console.log("Read file error: ".red, readFileErr);
        }

    });
});

标签: node.jsamazon-web-servicesexpressamazon-s3es6-promise

解决方案


如果不是代码清晰/简单(这是我的第一个答案的重点),您希望并发性能(不是多任务处理)替代,更清晰的代码可能是这样的:

const loopAllImageAndAddToList = async (blockContent) => {
  const imgList = [];
  for (const bc of blockContent)
    if (bc.blockElement.name === "imgBlockContent")
      imgList.push(getImage(bc.blockElement.imgUrl)
       .then(temp => ({ key: bc.blockElement.imgUrl, binaryImg: temp.Body }))


  return Promise.all(imgList);
}

或者,如果您喜欢链接代码并且不喜欢使用这些return语句:

const loopAllImageAndAddToList = async (blockContent) => Promise.all(
  blockContent.reduce((imgList, bc) =>
    bc.blockElement.name !== 'imgBlockContent'
      ? imgList
      : imgList.concat(
        getImage(bc.blockElement.imgUrl)
          .then(temp => ({ key: bc.blockElement.imgUrl, binaryImg: temp.Body }))
      ), [])
)
      

推荐阅读