使用 AWS-SDK 为节点和蓝鸟从承诺中返回的数据
Data returned from promises with AWS-SDK for node and bluebird
我正在尝试为 AWS 中的每个区域获取所有已注册的弹性 IP。我目前正在处理的代码如下:
logger.info('About to fetch Regions');
ec2.describeRegionsPromised({}).then(function (data) {
var addressesPromises = [];
logger.info('Fetched Regions');
logger.info(data);
_.forEach(data.Regions, function (region) {
var ec2Addresses = _.create(ec2, {region: region.RegionName});
addressesPromises.push(ec2Addresses.describeAddressesPromised());
});
logger.info('About to fetch addresses per region');
return Promise.all(addressesPromises);
}).then(function (data) {
logger.info('Fetched addresses per region');
logger.debug(data);
}).catch(function (err) {
logger.error('There was an error when fetching regions and addresses');
logger.error(err);
});
这工作正常,但我的问题是我正在查看第二个 .then
promised-callback 函数 data
参数,它的数据是一个与 相同的数组第一次请求返回的区域长度.
我知道我只在一个区域使用了 1 个弹性 IP。对于所有其他地区,我没有任何关联。
返回的Regions如下(其实是格式化的JSON):
Regions=[RegionName=eu-west-1, Endpoint=ec2.eu-west-1.amazonaws.com, RegionName=ap-southeast-1, Endpoint=ec2.ap-southeast-1.amazonaws.com, RegionName=ap-southeast-2, Endpoint=ec2.ap-southeast-2.amazonaws.com, RegionName=eu-central-1, Endpoint=ec2.eu-central-1.amazonaws.com, RegionName=ap-northeast-1, Endpoint=ec2.ap-northeast-1.amazonaws.com, RegionName=us-east-1, Endpoint=ec2.us-east-1.amazonaws.com, RegionName=sa-east-1, Endpoint=ec2.sa-east-1.amazonaws.com, RegionName=us-west-1, Endpoint=ec2.us-west-1.amazonaws.com, RegionName=us-west-2, Endpoint=ec2.us-west-2.amazonaws.com]
在 JSON 中将是:
{ Regions: [] } //and so on
返回的弹性IP如下:
[ { Addresses: [ [PublicIp=XX.XX.XXX.XXX, AllocationId=eipalloc-XXXXXXXX, Domain=vpc] ] },
{ Addresses: [ [PublicIp=XX.XX.XXX.XXX, AllocationId=eipalloc-XXXXXXXX, Domain=vpc] ] },
{ Addresses: [ [PublicIp=XX.XX.XXX.XXX, AllocationId=eipalloc-XXXXXXXX, Domain=vpc] ] },
{ Addresses: [ [PublicIp=XX.XX.XXX.XXX, AllocationId=eipalloc-XXXXXXXX, Domain=vpc] ] },
{ Addresses: [ [PublicIp=XX.XX.XXX.XXX, AllocationId=eipalloc-XXXXXXXX, Domain=vpc] ] },
{ Addresses: [ [PublicIp=XX.XX.XXX.XXX, AllocationId=eipalloc-XXXXXXXX, Domain=vpc] ] },
{ Addresses: [ [PublicIp=XX.XX.XXX.XXX, AllocationId=eipalloc-XXXXXXXX, Domain=vpc] ] },
{ Addresses: [ [PublicIp=XX.XX.XXX.XXX, AllocationId=eipalloc-XXXXXXXX, Domain=vpc] ] },
{ Addresses: [ [PublicIp=XX.XX.XXX.XXX, AllocationId=eipalloc-XXXXXXXX, Domain=vpc] ] } ]
在响应中,我有一个对象数组,其中每个区域请求的对象键值都相同,这是错误的。
我希望在第二个响应中每个区域的值分辨率,将其余部分设置为 null、undefined 或类似的。
总结一下。我不明白为什么解析一组承诺的值(使用 .all)会在每个点得到一组相同的值——这不是预期的结果。
这是怎么回事?提前致谢!
我发现了问题。
正如 @Roamer-1888 指出的 ec2Addresses 对象的创建不正确。相反,我应该使用 EC2 对象的 AWS SDK 构造函数创建一个新实例。然而,问题的关键是另一个。首先是代码...
logger.info('About to fetch Regions');
ec2.describeRegionsPromised({}).then(function (data) {
var addressesPromises = [];
logger.info('Fetched Regions');
_.forEach(data.Regions, function (region) {
var ec2Addresses = AWS.ec2(
{
region: region.RegionName,
endpoint: region.Endpoint
}
);
addressesPromises.push(ec2Addresses.describeAddressesPromised());
});
logger.info('About to fetch addresses per region');
return Promise.all(addressesPromises);
}).then(function (data) {
logger.info(arguments);
logger.info('Fetched addresses per region');
logger.debug(data);
}).catch(function (err) {
logger.error('There was an error when fetching regions and addresses');
logger.error(err);
});
正如您在这里注意到的那样,ec2Addresses
是通过调用 AWS.ec2()
而不是 new AWS.ec2()
创建的,这是因为 AWS 承诺的模块创建了对象并且 return 它回来承诺它。 (https://github.com/davidpelayo/aws-promised/blob/master/ecs.js):
'use strict';
var AWS = require('aws-sdk');
var memoize = require('lodash/function/memoize');
var promisifyAll = require('./lib/util/promisifyAll');
function ecs(options) {
return promisifyAll(new AWS.ECS(options));
}
/**
* Returns an instance of AWS.ECS which has Promise methods
* suffixed by "Promised"
*
* e.g.
* createService => createServicePromised
*
* @param options
*/
module.exports = memoize(ecs);
问题出在最后一行代码:
module.exports = memoize(ecs)
这行代码 正在缓存先前的执行,包括其先前的配置 。
事实证明,我最终调试了应用程序,我意识到正在执行的承诺数组的区域和端点是相同的,并且那里有一个错误。
通过删除 memoize(ecs)
,我得到的预期结果是:
info: Fetched addresses per region
debug: Addresses=[], Addresses=[], Addresses=[], Addresses=[], Addresses=[], Addresses=[PublicIp=XX.XXX.XXX.XXX, AllocationId=eipalloc-XXXXXX, Domain=vpc], Addresses=[], Addresses=[], Addresses=[]
感谢阅读和帮助。
我找到了一种无需创建新 EC2 对象即可请求不同区域地址的方法。换句话说,通过重用现有的 EC2 实例,通过如下方式切换端点:
_.forEach(data.Regions, function (region) {
//var ec2Addresses = AWS.ec2(
// {
// region: region.RegionName,
// endpoint: region.Endpoint
// }
//);
var ep = new AWS.Endpoint(region.Endpoint);
ec2.config.region = region.RegionName;
ec2.endpoint = ep;
addressesPromises.push(ec2.describeAddressesPromised());
});
logger.info('About to fetch addresses per region');
我正在尝试为 AWS 中的每个区域获取所有已注册的弹性 IP。我目前正在处理的代码如下:
logger.info('About to fetch Regions');
ec2.describeRegionsPromised({}).then(function (data) {
var addressesPromises = [];
logger.info('Fetched Regions');
logger.info(data);
_.forEach(data.Regions, function (region) {
var ec2Addresses = _.create(ec2, {region: region.RegionName});
addressesPromises.push(ec2Addresses.describeAddressesPromised());
});
logger.info('About to fetch addresses per region');
return Promise.all(addressesPromises);
}).then(function (data) {
logger.info('Fetched addresses per region');
logger.debug(data);
}).catch(function (err) {
logger.error('There was an error when fetching regions and addresses');
logger.error(err);
});
这工作正常,但我的问题是我正在查看第二个 .then
promised-callback 函数 data
参数,它的数据是一个与 相同的数组第一次请求返回的区域长度.
我知道我只在一个区域使用了 1 个弹性 IP。对于所有其他地区,我没有任何关联。
返回的Regions如下(其实是格式化的JSON):
Regions=[RegionName=eu-west-1, Endpoint=ec2.eu-west-1.amazonaws.com, RegionName=ap-southeast-1, Endpoint=ec2.ap-southeast-1.amazonaws.com, RegionName=ap-southeast-2, Endpoint=ec2.ap-southeast-2.amazonaws.com, RegionName=eu-central-1, Endpoint=ec2.eu-central-1.amazonaws.com, RegionName=ap-northeast-1, Endpoint=ec2.ap-northeast-1.amazonaws.com, RegionName=us-east-1, Endpoint=ec2.us-east-1.amazonaws.com, RegionName=sa-east-1, Endpoint=ec2.sa-east-1.amazonaws.com, RegionName=us-west-1, Endpoint=ec2.us-west-1.amazonaws.com, RegionName=us-west-2, Endpoint=ec2.us-west-2.amazonaws.com]
在 JSON 中将是:
{ Regions: [] } //and so on
返回的弹性IP如下:
[ { Addresses: [ [PublicIp=XX.XX.XXX.XXX, AllocationId=eipalloc-XXXXXXXX, Domain=vpc] ] },
{ Addresses: [ [PublicIp=XX.XX.XXX.XXX, AllocationId=eipalloc-XXXXXXXX, Domain=vpc] ] },
{ Addresses: [ [PublicIp=XX.XX.XXX.XXX, AllocationId=eipalloc-XXXXXXXX, Domain=vpc] ] },
{ Addresses: [ [PublicIp=XX.XX.XXX.XXX, AllocationId=eipalloc-XXXXXXXX, Domain=vpc] ] },
{ Addresses: [ [PublicIp=XX.XX.XXX.XXX, AllocationId=eipalloc-XXXXXXXX, Domain=vpc] ] },
{ Addresses: [ [PublicIp=XX.XX.XXX.XXX, AllocationId=eipalloc-XXXXXXXX, Domain=vpc] ] },
{ Addresses: [ [PublicIp=XX.XX.XXX.XXX, AllocationId=eipalloc-XXXXXXXX, Domain=vpc] ] },
{ Addresses: [ [PublicIp=XX.XX.XXX.XXX, AllocationId=eipalloc-XXXXXXXX, Domain=vpc] ] },
{ Addresses: [ [PublicIp=XX.XX.XXX.XXX, AllocationId=eipalloc-XXXXXXXX, Domain=vpc] ] } ]
在响应中,我有一个对象数组,其中每个区域请求的对象键值都相同,这是错误的。
我希望在第二个响应中每个区域的值分辨率,将其余部分设置为 null、undefined 或类似的。
总结一下。我不明白为什么解析一组承诺的值(使用 .all)会在每个点得到一组相同的值——这不是预期的结果。
这是怎么回事?提前致谢!
我发现了问题。 正如 @Roamer-1888 指出的 ec2Addresses 对象的创建不正确。相反,我应该使用 EC2 对象的 AWS SDK 构造函数创建一个新实例。然而,问题的关键是另一个。首先是代码...
logger.info('About to fetch Regions');
ec2.describeRegionsPromised({}).then(function (data) {
var addressesPromises = [];
logger.info('Fetched Regions');
_.forEach(data.Regions, function (region) {
var ec2Addresses = AWS.ec2(
{
region: region.RegionName,
endpoint: region.Endpoint
}
);
addressesPromises.push(ec2Addresses.describeAddressesPromised());
});
logger.info('About to fetch addresses per region');
return Promise.all(addressesPromises);
}).then(function (data) {
logger.info(arguments);
logger.info('Fetched addresses per region');
logger.debug(data);
}).catch(function (err) {
logger.error('There was an error when fetching regions and addresses');
logger.error(err);
});
正如您在这里注意到的那样,ec2Addresses
是通过调用 AWS.ec2()
而不是 new AWS.ec2()
创建的,这是因为 AWS 承诺的模块创建了对象并且 return 它回来承诺它。 (https://github.com/davidpelayo/aws-promised/blob/master/ecs.js):
'use strict';
var AWS = require('aws-sdk');
var memoize = require('lodash/function/memoize');
var promisifyAll = require('./lib/util/promisifyAll');
function ecs(options) {
return promisifyAll(new AWS.ECS(options));
}
/**
* Returns an instance of AWS.ECS which has Promise methods
* suffixed by "Promised"
*
* e.g.
* createService => createServicePromised
*
* @param options
*/
module.exports = memoize(ecs);
问题出在最后一行代码:
module.exports = memoize(ecs)
这行代码 正在缓存先前的执行,包括其先前的配置 。
事实证明,我最终调试了应用程序,我意识到正在执行的承诺数组的区域和端点是相同的,并且那里有一个错误。
通过删除 memoize(ecs)
,我得到的预期结果是:
info: Fetched addresses per region
debug: Addresses=[], Addresses=[], Addresses=[], Addresses=[], Addresses=[], Addresses=[PublicIp=XX.XXX.XXX.XXX, AllocationId=eipalloc-XXXXXX, Domain=vpc], Addresses=[], Addresses=[], Addresses=[]
感谢阅读和帮助。
我找到了一种无需创建新 EC2 对象即可请求不同区域地址的方法。换句话说,通过重用现有的 EC2 实例,通过如下方式切换端点:
_.forEach(data.Regions, function (region) {
//var ec2Addresses = AWS.ec2(
// {
// region: region.RegionName,
// endpoint: region.Endpoint
// }
//);
var ep = new AWS.Endpoint(region.Endpoint);
ec2.config.region = region.RegionName;
ec2.endpoint = ep;
addressesPromises.push(ec2.describeAddressesPromised());
});
logger.info('About to fetch addresses per region');