使用承诺以递归方式检索分页数据

Retrieve paginated data recursively using promises

本文关键字:检索 分页 数据 方式 递归 承诺      更新时间:2023-09-26

我正在使用一个以分页形式返回数据的函数。因此,它将返回最多 100 个项目和一个用于检索接下来 100 个项目的键。我想检索所有可用的项目。

如何递归实现此目的?递归在这里是一个不错的选择吗?我可以在没有递归的情况下以任何其他方式做到这一点吗?

我正在使用蓝鸟 3x 作为承诺库。

以下是我想要实现的目标的片段:

getEndpoints(null, platformApplication)
  .then(function(allEndpoints) {
    // process on allEndpoints
  });

function getEndpoints(nextToken, platformApplication) {
  var params = {
    PlatformApplicationArn: platformApplication
  };
  if (nextToken) {
    params.NextToken = nextToken;
  }
  return sns.listEndpointsByPlatformApplicationAsync(params)
    .then(function(data) {
      if (data.NextToken) {
        // There is more data available that I want to retrieve.
        // But the problem here is that getEndpoints return a promise
        // and not the array. How do I chain this here so that 
        // in the end I get an array of all the endpoints concatenated.
        var moreEndpoints = getEndpoints(data.NextToken, platformApplication);
        moreEndpoints.push.apply(data.Endpoints, moreEndpoints);
      }
      return data.Endpoints;
    });
}

但问题是,如果有更多的数据要检索(见if (data.NextToken) { ... }),我如何将承诺链接起来,以便最终获得所有端点的列表等。

递归可能是获取所有端点的最简单方法。

function getAllEndpoints(platformApplication) {
    return getEndpoints(null, platformApplication);
}
function getEndpoints(nextToken, platformApplication, endpoints = []) {
  var params = {
    PlatformApplicationArn: platformApplication
  };
  if (nextToken) {
    params.NextToken = nextToken;
  }
  return sns.listEndpointsByPlatformApplicationAsync(params)
    .then(function(data) {
      endpoints.push.apply(endpoints, data.Endpoints);
      if (data.NextToken) {
          return getEndpoints(data.NextToken, platformApplication, endpoints);
      } else {
          return endpoints;
      }
    });
}

对于从分页端点递归获取和返回数据的更通用的示例,我想出了以下内容:

getData(page, dataArray) {
  return new Promise((resolve, reject) => {
    getEndpointHere(
      {         
        page,
        pageSize: 50,
      },     
      (err, result) => {
        if (err)
          return console.error("there was a problem retrieving your data");          
        dataArray = dataArray.concat(result);
        if (result.length < 50) {
          resolve(dataArray);
        } else {
          resolve(getData(page + 1, dataArray));
        }
      }
    );
  });
}
getData(1, [])
.then((res) => {      
  console.log("SEVERAL PAGES OF DATA", res);
})

此示例使用回调 -- (err, result) -- 但是,可以提取该逻辑来处理来自终结点的响应。我消耗的资源不返回光标或"下一个"标记,指示是否有更多记录,因此我使用响应是否少于 50 条记录的逻辑作为继续请求更多数据的基础。