【问题标题】:Loop through AWS Lambda Nodejs SDK function循环通过 AWS Lambda Nodejs SDK 函数
【发布时间】:2017-11-22 05:48:25
【问题描述】:

我是 Nodejs 新手,无法理解这个问题:我尝试对数组运行 describe 函数,而 AWS 函数似乎在 main 函数完成后运行。

这是主要功能:(遍历 ACM ARN 列表并检查状态)

var checkCertStatus = function(resolveObj){
    var promise = new Promise(function(resolve, reject){

        console.log('1');
        var retObj='';
        resolveObj.Items.forEach(function(element) {
            var certDescribeParams = {
                CertificateArn: element.sslCertId
            };
            console.log('2');
            acm.describeCertificate(certDescribeParams, function(err, data) {
                if(err) reject(new Error(err));
                else     {
                    console.log(data.Certificate.DomainName + ': ' + data.Certificate.Status);
                    retObj+=data;
                }
            });
        });
        console.log('3');
        resolve(retObj);
        return promise;
    })
}

根据调试日志,假设有2项需要处理,我得到的是:

1
2
2
3
example.com: ISSUED
example2.com: ISSUED

基本上,我需要将此结果传递给链中的下一个函数(带有承诺和东西)。

【问题讨论】:

    标签: javascript node.js aws-lambda aws-sdk-nodejs


    【解决方案1】:

    欢迎使用 Node.js!一般来说,学习异步编程风格可能会有所帮助。特别是,您似乎混合了Promisescallbacks,这可能会使这个示例比它需要的更加混乱。我建议使用 AWS SDK 的内置功能将响应转换为 Promise。

    我注意到的第一件事是您正在手动构造一个带有解析/拒绝功能的 Promise。除非您正在创建库,否则这通常是一个危险信号。大多数其他库都支持您可以简单地使用和链接的 Promises。 (这包括 AWS 开发工具包,如上所述。)

    我注意到的第二件事是您的 checkCertStatus 函数没有返回任何内容。它创建了一个 Promise,但最后没有返回它。您的 return promise; 行实际上在用于创建 Promise 的回调函数中。

    就个人而言,在使用 Promises 时,我更喜欢使用 Bluebird 库。它提供了比原生更全功能的 Promises,包括 map 等方法。方便的是,AWS SDK 可以通过AWS.config.setPromisesDependency() 配置为与替代的 Promise 构造函数一起使用,如文档中的here

    为了简化您的逻辑,您可以尝试以下方式(未经测试的代码):

    const Promise = require('bluebird');
    AWS.config.setPromisesDependency(Promise);
    
    const checkCertStatus = (resolveObj) => {
        const items = resolveObj.Items;
        console.log(`Mapping ${items.length} item(s)`);
        return Promise.resolve(items)
            .map((item) => {
                const certDescribeParams = {
                    CertificateArn: item.sslCertId,
                };
                console.log(`Calling describeCertificate for ${item.sslCertId}`);
                return acm.describeCertificate(certDescribeParams)
                    .promise()
                    .then((data) => {
                        console.log(`${data.Certificate.DomainName}: ${data.Certificate.Status}`);
                        return data;
                    });
            });
    };
    

    我们将checkCertStatus 定义为一个接收resolveObj 并返回从resolveObj.Items 开始的Promise 链的函数。 (如果您还不熟悉Arrow Functions,我深表歉意。)此链中的第一步也是唯一的一步是将items 数组映射到从acm.describeCertificate 方法返回的新Promises 数组。如果这些单个 Promise 中的任何一个失败,顶级 Promise 链也将拒绝。否则,顶级 Promise 链将解析为结果数组。 (请注意,我包含一个无关紧要的 .then 步骤只是为了记录单个结果,但您可以完全删除该子句。)

    希望这会有所帮助,如果我在代码中留下任何错误,我深表歉意。

    【讨论】:

    • 查看我的答案,我认为,而不是resolve/.map 组合,您可以只使用Promise.map(items, <func>),其中 是上面.map 的参数。它基本上是一种速记。
    猜你喜欢
    • 1970-01-01
    • 2022-11-24
    • 2021-06-05
    • 1970-01-01
    • 2018-07-07
    • 1970-01-01
    • 2019-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多