循环访问AWS Lambda Nodejs SDK功能

时间:2017-11-21 02:33:29

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

我是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

基本上,我需要将这个结果传递给链中的下一个函数(带有promise和stuff)。

1 个答案:

答案 0 :(得分:1)

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

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

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

就个人而言,在使用Promises时,我更喜欢使用Bluebird库。它提供了比本机更多功能齐全的Promise,包括map等方法。方便地,AWS SDK可以配置为通过AWS.config.setPromisesDependency()通过here处理备用Promise构造函数。

为了简化您的逻辑,您可以尝试沿着这些方向(未经测试的代码):

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方法返回的新Promise数组。如果这些个别Promise中的任何一个失败,顶级Promise链也将拒绝。否则,顶级Promise链将解析为结果数组。 (请注意,我添加了一个不必要的.then步骤来记录单个结果,但您可以完全删除该子句。)

希望这会有所帮助,如果我在代码中遗漏了任何错误,我会道歉。