我正在使用AWS Node SDK执行以下任务 -
我要解开的部分是第4步,列出了每个群集的服务。基本上每个群集调用列表服务,每个响应只能返回10个项目,因此递归调用该函数以查看是否有另一个页面令牌退出。每个响应都被推送到一个数组。然后有一个最终的Promise.all打印出所有的回复。问题是只捕获了初始调用,而不是下一个令牌的任何递归调用。任何帮助将不胜感激:))
function getLiveCluster() {
var liveClusterName = 'xx1-app-ecs'
// Filter out the required clusters
clustersAry.forEach(function(cluster) {
if (cluster && cluster.clusterArns && cluster.clusterArns.length > 0) {
cluster.clusterArns.forEach(function(clusterArns) {
if (clusterArns.indexOf(liveClusterName) > -1) {
var serviceParams = {
cluster: clusterArns,
maxResults: 10,
nextToken: ''
};
ecsRegionParams.region = cluster.RegionName;
ecs = new aws.ECS(ecsRegionParams);
getClusterServices(serviceParams)
}
});
}
});
Promise.all(promiseAry2).then(() => {
console.log('All services <<<<<<<<<<<<\n', serviceAry)
});
}
function getClusterServices(serviceParams) {
promiseAry2.push(ecs.listServices(serviceParams).promise().then(function(data) {
serviceAry.push({
cluster: serviceParams.cluster,
service: data.serviceArns
});
if (data.nextToken) {
serviceParams.nextToken = data.nextToken;
getClusterServices(serviceParams)
}
}).catch((err) => {}));
}
在调试Promise.all数组之后,仍有待许可的承诺,如此处所示 -
"> All promiseAry2 <<<<<<<<<<<<
[ Promise { undefined },
Promise { undefined },
Promise { undefined },
Promise { undefined },
Promise { undefined },
Promise { undefined },
Promise { undefined },
Promise { <pending> },
Promise { <pending> },
Promise { <pending> },
Promise { <pending> } ]"
如何确保承诺完成的任何想法?
谢谢 - 这是一段代码,只需一个小小的调整就可以了。需要重置ECS的区域,如此处所示 -
// Reset ECS to current cluster region
ecsRegionParams.region = cluster.RegionName;
// Store the request for this cluster as a promise
promiseAry.push(
getClusterServices(
new aws.ECS(ecsRegionParams),
serviceParams
)
)
新输出将数据传回到单独的对象中,如此处所示 -
All arrayOfarraysOfServices <<<<<<<<<<<<
[ [ { cluster: 'arn:aws:ecs:eu-central-1:0123456789:cluster/xx1-app-ecs-ECSCluster-1',
service:
[ 'arn:aws:ecs:eu-central-1:0123456789:service/service-1',
'arn:aws:ecs:eu-central-1:0123456789:service/service-2',
'arn:aws:ecs:eu-central-1:0123456789:service/service-3',
'arn:aws:ecs:eu-central-1:0123456789:service/service-4',
'arn:aws:ecs:eu-central-1:0123456789:service/service-5',
'arn:aws:ecs:eu-central-1:0123456789:service/service-6',
'arn:aws:ecs:eu-central-1:0123456789:service/service-7',
'arn:aws:ecs:eu-central-1:0123456789:service/service-8',
'arn:aws:ecs:eu-central-1:0123456789:service/service-9',
'arn:aws:ecs:eu-central-1:0123456789:service/service-10' ] },
{ cluster: 'arn:aws:ecs:eu-central-1:0123456789:cluster/xx1-app-ecs-ECSCluster-1',
service:
[ 'arn:aws:ecs:eu-central-1:0123456789:service/service-11',
'arn:aws:ecs:eu-central-1:0123456789:service/service-12' ] } ],
[ { cluster: 'arn:aws:ecs:eu-central-1:0123456789:cluster/xx1-app-ecs-ECSCluster-2',
service:
[ 'arn:aws:ecs:eu-central-1:0123456789:service/service-1',
'arn:aws:ecs:eu-central-1:0123456789:service/service-2',
'arn:aws:ecs:eu-central-1:0123456789:service/service-3',
'arn:aws:ecs:eu-central-1:0123456789:service/service-4',
'arn:aws:ecs:eu-central-1:0123456789:service/service-5',
'arn:aws:ecs:eu-central-1:0123456789:service/service-6',
'arn:aws:ecs:eu-central-1:0123456789:service/service-7',
'arn:aws:ecs:eu-central-1:0123456789:service/service-8',
'arn:aws:ecs:eu-central-1:0123456789:service/service-9',
'arn:aws:ecs:eu-central-1:0123456789:service/service-10' ] },
{ cluster: 'arn:aws:ecs:eu-central-1:0123456789:cluster/xx1-app-ecs-ECSCluster-2',
service:
[ 'arn:aws:ecs:eu-central-1:0123456789:service/service-11',
'arn:aws:ecs:eu-central-1:0123456789:service/service-12' ] } ],
[ { cluster: 'arn:aws:ecs:eu-central-1:0123456789:cluster/xx1-app-ecs-ECSCluster-3',
service:
[ 'arn:aws:ecs:eu-central-1:0123456789:service/service-1',
'arn:aws:ecs:eu-central-1:0123456789:service/service-2',
'arn:aws:ecs:eu-central-1:0123456789:service/service-3' ] } ],
[ { cluster: 'arn:aws:ecs:eu-central-1:0123456789:cluster/xx1-app-ecs-ECSCluster-4',
service: [] } ],
[ { cluster: 'arn:aws:ecs:eu-central-1:0123456789:cluster/xx1-app-ecs-ECSCluster-5',
service: [] } ]]
我接下来要做的是过滤推送,这样如果群集arn已经存在,那么数据会连接到现有条目。
EG Cluster arn:aws:ecs:eu-central-1:0123456789:cluster / xx1-app-ecs-ECSCluster-1有12个服务,而不是有2个对象,它将拥有12个服务。< / p>
在函数getClusterServices中执行此操作是否明智,或者在Promise.all中完成所有承诺之后是否应该这样做?
这是一个解决方案,将数组数组转换回单个数组,查找重复项,将重复的集群服务附加到当前集群服务,然后删除重复...生成最终的分页集群服务数组。
Promise.all(promiseAry).then((arrayOfarraysOfServices) => {
// Consolidate data into singular array
var singularAry = [];
// Recursively print array of unknown dimensions
function morphToSingularArray(arr) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] instanceof Array) {
morphToSingularArray(arr[i]);
} else {
singularAry.push(arr[i]);
}
}
return singularAry;
}
var listAry = morphToSingularArray(arrayOfarraysOfServices);
// Merge services for duplicate clusters
// First cluster in array
for (var i = 0; i < listAry.length; ++i) {
// Second cluster in array
for (var j = i + 1; j < listAry.length; ++j) {
// Matching
if (listAry[i].cluster === listAry[j].cluster) {
// Does service object exist
if (listAry[j].service && listAry[j].service.length > 0) {
var serviceAry = listAry[j].service;
// Iterate over second cluster services, appending to first cluster services
for (var x = 0; x < serviceAry.length; ++x) {
listAry[i].service.push(serviceAry[x]);
}
}
// Delete second cluster after appending
listAry.splice(j--, 1);
}
}
}
console.log('Paginated data array\n', listAry)
}).catch((e) => console.log(e));
可以将map用作上述三重数组解决方案的清洁方法吗?
答案 0 :(得分:1)
这是你的问题,你将promises传递给promises数组,然后你将每个promises本身可能会在数组传递到Promise.all
之后将更多的promise推送到同一个数组中。
在全局维护所有数据的同时在这样的回调中创建承诺是一个已知的anti-pattern with promises。
Promise解析为一个值并且可以链接,这意味着我们通常可以通过它们传播它们的结果,而不是拥有全局数据。
对我来说,对于clustersAry
中的每个元素,您都希望获得其服务(如果存在),并且每个服务都以递归方式获取其服务等。
您应该让getClusterServices
本身返回一个承诺,该承诺将解析为通过递归级别收集的一系列服务。
这是基于以上评论的一种方法:
function getLiveCluster() {
const liveClusterName = 'xx1-app-ecs'
// Filter out the required clusters
clustersAry.forEach(cluster => {
if (cluster && cluster.clusterArns && cluster.clusterArns.length > 0) {
cluster.clusterArns.forEach(clusterArns => {
if (clusterArns.indexOf(liveClusterName) > -1) {
const serviceParams = {
cluster: clusterArns,
maxResults: 10,
nextToken: ''
};
// store the request for this cluster as a promise
promiseAry.push(
getClusterServices(
new aws.ECS(cluster.RegionName),
serviceParams
)
)
}
});
}
});
Promise.all(promiseAry).then((arrayOfarraysOfServices) => {
console.log('All services <<<<<<<<<<<<\n', arrayOfarraysOfServices)
});
}
function getClusterServices(ecs, serviceParams, clusterServiceAry = []) {
// return a promise here that resolves
// with an array of services for the given serviceParams
// once all recursive service requests are finished
return ecs
.listServices(serviceParams)
.promise()
.then(data => {
clusterServiceAry.push({
cluster: serviceParams.cluster,
service: data.serviceArns
});
return !data.nextToken
? clusterServiceAry // nextToken is falsy, we are finished, resolve with the service array
: getClusterServices(
ecs,
// update the token by creating a new object
// rather than mutating the existing one
Object.assign(
{},
serviceParams,
{
nextToken: data.nextToken
}
),
// pass the cluster service array so we can accumulate
// the services
clusterServiceAry
)
})
}