简体   繁体   中英

Loop through AWS Lambda Nodejs SDK function

I'm new to Nodejs and having trouble understand this issue: I tried to run a describe function against an array, and the AWS function seems to run after the main function has finished.

Here's the main function: (loop thru a list of ACM ARNs and check the status)

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

Based on the debug log, assuming there are 2 items need to be processed, what I got:

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

Basically, I need to pass this result to the next function in the chain (with promise and stuff).

Welcome to Node.js! Speaking generally, it might be helpful to study up on the asynchronous programming style. In particular, you seem to be mixing Promises and callbacks , which may make this example more confusing than it needs to be. I suggest using the AWS SDK's built-in feature to convert responses to Promises.

The first thing I notice is that you are manually constructing a Promise with a resolve/reject function. This is often a red flag unless you are creating a library. Most other libraries support Promises which you can simply use and chain. (This includes AWS SDK, as mentioned above.)

The second thing I notice is that your checkCertStatus function does not return anything. It creates a Promise but does not return it at the end. Your return promise; line is actually inside the callback function used to create the Promise.

Personally, when working with Promises, I prefer to use the Bluebird library. It provides more fully-featured Promises than native, including methods such as map . Conveniently, the AWS SDK can be configured to work with an alternative Promise constructor via AWS.config.setPromisesDependency() as documented here .

To simplify your logic, you might try something along these lines (untested code):

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

We're defining checkCertStatus as a function which takes in resolveObj and returns a Promise chain starting from resolveObj.Items . (I apologize if you are not yet familiar with Arrow Functions .) The first and only step in this chain is to map the items array to a new array of Promises returned from the acm.describeCertificate method. If any one of these individual Promises fails, the top-level Promise chain will reject as well. Otherwise, the top-level Promise chain will resolve to an array of the results. (Note that I included an inessential .then step just to log the individual results, but you could remove that clause entirely.)

Hope this helps, and I apologize if I left any mistakes in the code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM