有什么办法可以将https响应保存到变量中?

时间:2019-07-24 15:15:35

标签: javascript node.js api https

我现在正在使用GitHub APi,JavaScript中的node.js和https模块。我需要从存储库中获取提交的总数。没有变量说明它的数量,因此我试图获取所有提交并仅对其进行计数,但是我需要对其进行迭代,因为它们是分页的

我试图从gitHub api中的函数中获取数据并尝试保存在局部变量中,但是当请求结束时,该变量为void。我试图将数据保存在全局变量中,在函数之前声明的变量中,尝试将其保存在本地文件中。但是我无法获取信息。 我也试图返回函数中的数据,但是我不能


    function getCommits(repository){
     let options {
          host: host,
           path: '/repos/'...
      }
     let request = https.request(options , (response) => {
            let body = '';
            response.on('data', (out) => {
                body += out;
                  } 
            });

     response.on('end', (out) => {
                json = JSON.parse(body);
                var i = json.length //This is the variable that I need to get out 
                                    //  from the function

            });
    }

该变量未定义或与我在开头声明的值相同

2 个答案:

答案 0 :(得分:0)

您遇到了各种各样的问题。对于初学者,我建议您阅读此答案How do I return the response from an asynchronous call,因为它应该可以帮助您了解返回异步检索的值(只能通过回调或Promise返回)的一些问题。

然后,我建议使用request-promise库而不是普通的http.request(),因为它都是较高的级别(为您积累了整个响应),将自动解析为JSON,并且支持一个promise接口。在循环浏览每个页面时非常有用。

然后,我们将使用asyncawait来简化使用异步操作的循环。

最后,您没有确切显示所有页面上的循环是如何工作的,所以我只为您提供一些伪代码,您将必须填写github的真实实现。 / p>

const rp = require('request-promise');

async function getAllCommits(baseURL) {
    // init counter
    let totalCommits = 0;

    // page number counter
    let pageNum = 0;

    // loop until we break out
    while (true) {
        // request desired page, auto parse JSON response
        try {
            // make github request, putting page in query string
            // the exact request is pseudo-code here, you have to construct
            // the desired URL you need for your specific request
            let data = await rp({uri: baseURL, json: true, qs: {page: pageNum++}});
        } catch(e) {
            // have to decide what to do about an error here (continue, abort, etc..)
            // for now, I'll just stop further processing, assuming you've requested
            // a page beyond what exists
            // But, this needs a more real error handling strategy based on what
            // github returns
            console.log(e);
            if (real error) {
                // stops further promising, rejects async promise
                throw e;
            } else {
                // breaks out of while loop
                break;
            }
        }
        // now iterate over the data and update the totalCommits variable

    }
    return totalCommits;
}

// sample usage
getAllCommits("http://somehost/someRepository").then(total => {
    console.log(total);
}).catch(e => {
    console.log(e);
});

您可能不了解有关getAllCommits()实现的一些事情:

  1. 这是一个async函数,总是返回一个promise,并使用您从该函数返回的任何值来解析该promise。
  2. 如果您在throw函数中async会拒绝返回的诺言,但将异常值作为拒绝原因。
  3. 只有async个功能可以使用await
  4. await暂停函数的内部执行,直到您等待的诺言得到解决或拒绝为止。
  5. await仅在等待诺言时才有用。
  6. 如果您正在等待的诺言成功解决,您将从await语句中获得一个值。
  7. 如果您正在等待的诺言被拒绝,它将本质上throw,并且捕获该错误的方法是使用try/catch,其语法类似于同步异常。
  8. async函数暂停了对await语句的内部执行,但是在第一个await时,它立即向外界返回了一个诺言,并且外界继续运行您的Javascript 。因此,async函数不会暂停整个执行序列,而只是async函数的内部。
  9. 这意味着async函数的结果是一个承诺,调用方必须在该承诺上使用await或对该承诺使用.then()才能获得返回的结果。
  10. li>

答案 1 :(得分:-1)

尝试编写此代码,on()函数将返回length的值,然后我们从函数中返回该值。

return response.on('end', (out) => {
   json = JSON.parse(body);
   return json.length;  
});