首页 > 解决方案 > JS 中的 Promise 和 Callbacks 问题

问题描述

我正在尝试从 S3 存储桶中获取对象列表,当我有对象列表时,我想为这些对象生成预签名 URL。我能弄清楚如何做到这一点的唯一方法是使用嵌套回调函数,如下所示:

exports.handler = async (event, context, callback) => {
console.log('processing event: %j', event);

const bucket = process.env['s3_bucket'];
if (!bucket) {
    callback(new Error("s3 bucket not set"));
}

const deviceId = event['deviceId'];

const params = getListObjectsParams(deviceId, bucket);
let count = 0;

await s3.listObjectsV2(params, function (err, data) {
    if (err) callback("Error getting image list: " + err);
    else {
        data.Contents.forEach(function (image) {
            count = count + 1;
            const objectParams = getObjectParams(bucket, image.Key);
            s3.getSignedUrl('getObject', objectParams, function (err, url) {
                if (err) {
                    console.log("Error");
                    console.log(err);
                    //TODO: log error getting pre signed url
                } else {
                    images.push(url);
                }
            });

        });
    }
});

callback(null, images);

};

我在返回图像数组时遇到了一些麻烦,因为函数在调用 listObjectsV2 和每个 getSignedUrl 完成之前完成。这是我的问题。

  1. 在完成执行功能之前,如何让执行等待承诺完成?
  2. 如果有更好的方法来布局这段代码,嵌套回调看起来很乱:(

标签: javascriptnode.jsamazon-web-servicesamazon-s3promise

解决方案


AWS JavaScript 开发工具包原生支持 Promise。而不是这个:

s3.listObjectsV2(params, function (err, data) {
    // do something with data here in the callback
});

写这个:

const data = await s3.listObjectsV2(params).promise();
// do something with data here

请注意,await只能在async函数中使用。如果您不在异步函数中,那么您可以按如下方式制作一个(立即调用的异步箭头函数):

(async () => {
    const data = await s3.listObjectsV2(params).promise();
    // do something with data here
})();

推荐阅读