【问题标题】:Why is my array coming back undefined outside of the function?为什么我的数组在函数之外返回未定义?
【发布时间】:2021-01-23 23:20:27
【问题描述】:

我正在尝试从这个函数中获取“msg”来对其进行数学运算,但它不断返回未定义。但是,在函数内我可以读取数据但不能对其进行数学运算。

let getArr = []
      const https = require('https')
        const options = {
          hostname: 'financialmodelingprep.com',
          port: 443,
          path: '/api/v3/quote/TSLA?apikey=?apikey=demo',
          method: 'GET'
        }
        
        const req = https.request(options, (res) => {
         
             res.on('data', (data) => {
             data = JSON.parse(data)
             data.map(( msg ) => {
                 //console.log(msg)
                 getArr.push(msg)
             })
          })        
        })  
     console.log(getArr.slice(-1)[0])     

【问题讨论】:

  • 从您的代码看来,您似乎是在 API 返回数据之前访问变量 getArr 您也可以在将数据推送到 getArr 变量后进行数学运算,即在 data.map 之后
  • 我有一个不同的函数,我希望这些数据可以转到。据我了解,这是一个异步函数。如何让它耐心等待然后更新全局变量?
  • 你可以使用 await 操作符看这个例子stackoverflow.com/questions/8775262/…
  • 你不知道你的回调 (res) => { 什么时候执行,所以设置一个全局变量没有帮助,因为你不知道什么时候访问那个全局变量,因为你不知道当它获得分配的数据时。如果要将数据传递给另一个函数,请在 (res) => { 回调中调用该函数:anotherFunc(data)。另外,即使你不需要它,你也不应该在这里使用.map(),当你不想返回任何东西时使用.forEach()
  • @NickParsons 谢谢

标签: javascript arrays api get request


【解决方案1】:

代码有两个问题。

  1. 在收到请求的响应之前,尝试访问处理https 请求的结果,即getArr 中保存的msg 条目:

    • data.map(( msg ) => {... 在回调函数中收到响应后执行。
    • console.log(getArr.slice(-1)[0]) 在向浏览器发出请求(可能已经发起网络请求,也可能尚未发起网络请求)之后同步执行,当然在回调被调用之前。

    规范答案:How do I return the response from an asynchronous call?

  2. HTTP(S) 响应以数据包的形式发送,无法保证第一个响应将包含要接收的所有 JSON 文本。

    • 代码必须连接传递给on("data", )的数据块,并且只尝试在on('end', ... )回调处理程序中解析完整的字符串。

    之前回复:SyntaxError: Unexpected end of JSON input at JSON.parse (... at IncomingMessage...

【讨论】:

  • 谢谢!我更新了代码以反映 nicks 的建议。
【解决方案2】:

您正试图在 async req 函数返回之前访问该变量。

试试:

let getArr = []
      const https = require('https')
        const options = {
          hostname: 'financialmodelingprep.com',
          port: 443,
          path: '/api/v3/quote/TSLA?apikey=?apikey=demo',
          method: 'GET'
        }
        
        const req = https.request(options, (res) => {
         
             res.on('data', (data) => {
             data = JSON.parse(data)
             data.map(( msg ) => {
                 //console.log(msg)
                 getArr.push(msg)
             })
             console.log(getArr.slice(-1)[0]);
          }) 
        })  
     //console.log(getArr.slice(-1)[0])     

如何让它“等待”然后更新全局变量:

我明白你在说什么,以及你可能对什么感到困惑。 JS 中的异步编程需要一些范式转换。当您编写异步代码时,您不希望它“等待”然后更新全局变量,您必须在该异步块内编写代码。话虽如此,您可以以更正常的“等待”和“更新”方式编写异步代码,但我建议您从复习异步理解开始。这是一个很好的链接,我觉得很有帮助:https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous

【讨论】:

  • 我很感激!尼克建议通过回叫将数据发送回来。你也是对的,但我不想单独在那个块中编写我的所有代码。我只需要一个数据。
猜你喜欢
  • 2014-06-04
  • 1970-01-01
  • 2021-11-15
  • 1970-01-01
  • 1970-01-01
  • 2020-03-28
  • 2022-01-16
  • 2021-03-23
相关资源
最近更新 更多