我是NodeJS的新手。我对如何在单个lambda函数中完成多个API调用感到困惑。这不是lambda / aws特定的问题,它更多的是与回调相关的混淆。
这是要求。
我想获取所有实例和所有RDS列表,并将它们收集在单个数组中并返回它们。
这里是我编写的一些代码,在语法上我已经验证了。
'use strict';
const AWS = require('aws-sdk');
function getInstancesByRegion(regionName) {
var instances = [];
var ec2withRegion = new AWS.EC2({
region: regionName
});
ec2withRegion.describeInstances({}, function(err, data) {
if (err) {
console.error(err.toString());
} else {
var currentTime = new Date();
console.log(currentTime.toString());
for (var r = 0, rlen = data.Reservations.length; r < rlen; r++) {
var reservation = data.Reservations[r];
for (var i = 0, ilen = reservation.Instances.length; i < ilen; ++i) {
var instance = reservation.Instances[i];
var name = '';
for (var t = 0, tlen = instance.Tags.length; t < tlen; ++t) {
if (instance.Tags[t].Key === 'Name') {
name = instance.Tags[t].Value;
}
}
instances.push({
id: instance.InstanceId,
type: instance.InstanceType,
name: name
});
}
}
return instances;
}
});
}
function getDatabasesByRegion(regionName) {
var dbInstances = [];
var rdsWithRegion = new AWS.RDS({
region: regionName
});
rdsWithRegion.describeDBInstances({}, function(err, data) {
if (err) {
console.error(err.toString());
} else {
var currentTime = new Date();
console.log(currentTime.toString());
for (var r = 0, rlen = data.DBInstances.length; r < rlen; r++) {
var dbInstance = data.DBInstances[r];
dbInstances.push({
id: dbInstance.DBInstanceIdentifier
});
}
return dbInstances;
}
});
}
exports.handler = (event, context, callback) => {
var ec2 = new AWS.EC2();
var params = {};
var resources = [];
ec2.describeRegions(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
for (var i = 0; i < data.Regions.length; i++) {
var regionName = data.Regions[i].RegionName;
console.log("Current RegionName is " + regionName);
resources.push({
region: regionName,
instances: getInstancesByRegion(regionName),
databases: getDatabasesByRegion(regionName)
});
}
});
callback(null, resources);
};
答案 0 :(得分:2)
如果您使用Javascript Promises而不是回调,您的代码可以更清晰。
AWS SDK使用.method(params).promise()
代替.method(params, callback)
来提供对Promise的支持。
参考:Using Javascript Promises (AWS SDK)
然后,您可以使用promises重写代码。 Promise.all()
是您用例的关键。
我就是这样做的......
const AWS = require('aws-sdk')
const ec2 = new AWS.EC2()
function getInstancesByRegion(regionName) {
const ec2withRegion = new AWS.EC2({
region: regionName,
})
return ec2withRegion.describeInstances({}).promise()
.then(data => data.Reservations.reduce((acc, reservation) => {
const instances = reservation.Instances.map(instance => ({
id: instance.InstanceId,
type: instance.InstanceType,
name: instance.Tags.find(tag => tag.Key === 'Name').Value,
}))
return acc.concat(instances)
}, []))
}
function getDatabasesByRegion(regionName) {
const rdsWithRegion = new AWS.RDS({
region: regionName,
})
return rdsWithRegion.describeDBInstances({}).promise()
.then(data => data.DBInstances.map(dbInstance => ({
id: dbInstance.DBInstanceIdentifier,
})))
}
function getResourcesByRegion(region) {
return Promise.all([
getInstancesByRegion(region),
getDatabasesByRegion(region),
])
.then(results => ({
region,
instances: results[0],
databases: results[1],
}))
}
exports.handler = (event, context, callback) => ec2.describeRegions({})
.promise()
.then((data) => {
const getResources = data.Regions
.map(region => getResourcesByRegion(region.RegionName))
return Promise.all(getResources)
})
.then(resources => callback(null, resources))
.catch(callback)