【问题标题】:Is there any way to save a https response in a varable?有什么方法可以将 https 响应保存在变量中?
【发布时间】:2019-07-24 15:15:35
【问题描述】:

我现在正在使用 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

            });
    }

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

【问题讨论】:

标签: javascript node.js api https


【解决方案1】:

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

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

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

最后,你并没有准确地展示所有页面的循环是如何工作的,所以我只给你一些伪代码,你必须填写 github 的真正实现。

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. 如果您在 async 函数中 throw 将拒绝返回的承诺,并将异常值作为拒绝原因。
  3. 只有async 函数可以使用await
  4. await 暂停函数的内部执行,直到您等待的承诺解决或拒绝。
  5. await 只在等待承诺时做一些有用的事情。
  6. 如果您等待的承诺成功解决,您将从await 语句中获得一个值。
  7. 如果您正在等待的 promise 被拒绝,它本质上将是 throw,捕获该错误的方法是使用 try/catch,其语法与同步异常类似。
  8. async 函数暂停其内部执行 await 语句,但在第一个 await 时,它立即向外部世界返回一个承诺,外部世界继续运行您的 Javascript。因此,async 函数不会暂停整个执行序列,只会暂停 async 函数的内部。
  9. 这意味着async 函数的结果是一个promise,调用者必须在该promise 上使用await 或在该promise 上使用.then() 以获得返回的结果。

【讨论】:

    【解决方案2】:

    试着写这个,on() 函数将返回长度值,然后我们从函数中返回该值。

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

    【讨论】:

    • 这不会从函数返回值。您只是从事件处理程序返回一个值。返回值只是返回到事件处理程序。它不是从主函数返回的。
    • 它不起作用,当我尝试调用它返回“未定义”的函数时
    • 另外,如果这行得通,OP 自己的代码也行。
    • 哦,是的,它在事件处理程序回调中的另一个函数中,感谢@jfriend00。我很感激:D
    猜你喜欢
    • 2019-09-20
    • 2016-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-01
    • 2021-03-07
    • 2015-11-26
    • 1970-01-01
    相关资源
    最近更新 更多