节点承诺不推送所有的数据到数组

我正在使用AWS Node SDK来完成以下任务 –

  1. 获取地区
  2. 获取每个区域的集群ARN
  3. 获取经过筛选的ECS群集列表。
  4. 获取过滤群集的服务

我要脱钩的部分是第4步,列出每个群集的服务。 从本质上来说,每个集群列出服务的调用每个响应只能返回10个项目,因此会recursion调用该函数以查看是否存在另一个页面标记。 每个响应被推送到一个数组。 然后有一个最后的Promise.all打印出所有的答复。 问题是只有最初的调用被捕获,而不是任何下一个令牌的recursion调用。 任何帮助将非常感激 :)

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

编辑1

在debuggingPromise.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> } ]" 

任何想法如何确保承诺完成?

回答1回应

谢谢你 – 这是一个类的代码,并与一个微小的周期很好地工作。 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群集arn:aws:ecs:eu-central-1:0123456789:cluster / xx1-app-ecs-ECSCluster-1有12个服务,而不是有2个对象,它将有12个服务。

在函数getClusterServices中执行此操作是明智的,还是应该在Promise.all中完成所有的promise后完成这个操作?

编辑2

这里有一个解决scheme,将arrays变换回单一arrays,find重复项,将重复的群集服务附加到当前的群集服务,然后删除重复项……生成最终的分页群集服务arrays。

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

地图可以作为一个更清洁的方法,以上三重数组解决scheme?

这是你的问题,你将承诺传递给一个承诺数组,然后你有这些承诺本身可能推动更多的承诺到同一个数组已经传递到Promise.all

在这样的callback中创build承诺,同时在全球范围内维护所有数据是一个有承诺的已知反模式 。

承诺解决了价值,可以链接,这意味着我们通常可以通过它们传播结果,而不是拥有全局数据。

在我看来,你想要为clustersAry每个元素获取它的服务(如果它们存在的话),并且为每一个这样的服务recursion地获得它们的服务等等。

你应该有getClusterServices本身返回一个承诺,将parsing成一个服务的数组,通过recursion级收集。

基于上面的评论,有一种方法:

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