如何迭代请求调用并将结果存储在对象中?

How to iterate request calls and store results in on object?

以下代码使用 GitHub API 检索有关发布的数据。不幸的是,这只有 returns 30(默认情况下)或最多 100 个项目。

request(`https://api.github.com/repos/${owner}/${repo}/releases?page=1&per_page=30`, options, function (error, response, body) {
    if (response.statusCode !== 200) {
        return console.log(`Error: response code ${response.statusCode}`)
    }

    let data = JSON.parse(body);

    data.forEach(function(element) {
        // do things with data
    });
});

使用 page 参数,应该可以检索超出每页最大数量的项目。问题是:如何迭代这些 request 调用和 return 一个包含所有结果的对象?

这是我尝试过的方法:

function getReleases(callback, page = 1) {
    request(`https://api.github.com/repos/${program.owner}/${program.repo}/releases?page=${page}&per_page=30`, options, function (error, response, body) {
        if (response.statusCode !== 200 || error) {
            console.log(`Error ${response.statusCode}`);
            callback(null) // not sure about this
        }

        let data = JSON.parse(body);
        callback(data);
    });
}

function formatReleaseData(data) {
    // do things with data
}

formatReleaseData(show_page_count);

以下是使用 ES6 生成器模拟同步请求并更好地控制流程的方法。 您可以阅读此 article 以获得更深入的概念。

我正在使用 bluebird 来承诺和管理生成器。

查看下面的代码。

const request = require('request');
const Promise = require('bluebird');


function promisifyRequest(currentPage) {
  const url = `https://api.github.com/repos/${owner}/${repo}/releases?page=${currentPage}&per_page=30`;

  return new Promise((resolve, reject) => {
    request(url, options, (err, res, content) => {
      if (res.statusCode !== 200) {
        return reject(res.statusCode);
      }
      resolve(JSON.parse(content));
    });
  });
}

function * doRequest() {
  const result = [];
  let currentPage = 1;
  //Might run until gets a empty array.
  while (true) {
    let data = yield promisifyRequest(currentPage);
    if (!data.length) break;
    //Appends the results of the current page to the total result.
    result.splice(result.length, 0, ...data);
    currentPage = currentPage + 1;
  }

  return result;
}


Promise.coroutine(doRequest)()
  .then(result => {
    //Do something with the result
  })
  .catch(errCode => console.log(`Error: response code ${errCode}`));