【问题标题】:Trouble with Promises and Callbacks in JSJS 中的 Promise 和 Callbacks 问题
【发布时间】:2019-10-24 03:40:42
【问题描述】:

我正在尝试从 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. 如果有更好的方法来布局这段代码,嵌套回调看起来很乱:(

【问题讨论】:

  • 您的代码显示使用了普通回调,并表明根本没有使用承诺。

标签: javascript node.js amazon-web-services amazon-s3 promise


【解决方案1】:

在完成函数执行之前,如何让执行等待 Promise 完成?

async 函数中,将await 放在promise 前面。

你已经完成了前两个,但s3.listObjectsV2 没有返回承诺

如果你想使用await,那么你必须convert the existing callback API to a promise

【讨论】:

    【解决方案2】:

    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
    })();
    

    【讨论】:

    • 感谢 listObjectsV2 的 .promise() 提示。那非常有用。结果他们没有 .promise() 调用 getSignedUrls (github.com/aws/aws-sdk-js/issues/1008)
    • 你可以promisify任何回调风格的异步函数。
    • 是的,这就是我最终所做的。
    猜你喜欢
    • 2020-12-31
    • 1970-01-01
    • 2020-12-19
    • 2018-02-18
    • 2020-03-25
    • 1970-01-01
    • 1970-01-01
    • 2013-12-16
    • 2020-11-25
    相关资源
    最近更新 更多