繁体   English   中英

尝试通过 js 使用 fetch。 它正在返回,就好像它实际上没有调用任何数据一样。 我哪里错了?

[英]Trying to use fetch via js. It's returning as if its not actually calling any data. Where am I going wrong?

我无法为此找到任何资源。 我所需要的只是在正确的方向上获得帮助,以便在某些 HTML 中使用一些有形的东西。所以基本上当我调用 console.log(keys) 时,我不会像以前那样在我的控制台中获得 json 对象。 项目特别要求通过获取以这种方式完成。

 function getFromSWAPI() { fetch("https://swapi.dev/api/people/1").then(function (response) { return response.json() }).then(function(data){ updateInfo(data) }).catch(function(err) { console.warn(err) }) } const updateInfo = responseJSON => { console.log(responseJSON.data) let keys = Object.keys(responseJSON.data) console.log(keys) }

这段代码有几处错误; 其中只有一个是您遇到日志记录问题的直接原因,但在这起作用之前它们都需要修复。

首先:为什么 console.log 不工作/为什么你会收到 TS 错误“无法在 Function.keys 将未定义或 null 转换为 object”?

因为responseJSON没有名为“data”的属性,因为 API 响应不包含名为“data”的属性。 我怀疑该名称出现在这里是因为您对 HTTP 响应是什么以及 Promise 的工作方式感到困惑。 让我们从头开始。

fetch返回一个HTTP 响应object,其中包含一些文本。 您可以通过以下方式访问该文本:

let text = await response.text()

或者,如果您使用链式.then处理程序(如您的示例中所示),您可以这样做:

.then((response) => {
    return response.text()
})

如果您知道文本是有效的 JSON(您知道),那么您可以提取文本并将其解析为一个值,只需一个操作: response.json() (这就是您正在做的)。

这将返回一个 Promise,其中包含由 JSON 编码的值。如果该值为 object,它将具有该 JSON 所描述的属性。

您的 object 将具有哪些属性? 在浏览器中打开 URL,您会看到它们:“birth_year”、“created”、“edited”、“eye_color”、“films”、“gender”、“hair_color”、“height”、“homeworld”、 “质量”,“名称”,“皮肤颜色”,“物种”,“星舰”,“网址”,“车辆”。

“数据”不在该列表中。

这就是您使用响应中的信息所做的事情:

.then(function (response) {
    return response.json()
})
.then(function(data){
    updateInfo(data)
})

因此,您将解析后的值直接传递给updateInfo function。

updateInfo function 然后尝试在接收到的值(不存在)上记录.data属性。 也就是说, .dataundefined

记录未定义的 object 不是错误。但是Object.keys如果提供了undefined将抛出:

Object.keys(undefined)
//> Uncaught TypeError: can't convert undefined to object

解决方法是从日志语句和Object.keys调用中删除.data

第二:那应该是你的第一个调试步骤。 即使不理解以上所有内容:如果对隐藏在值中的数据点的操作失败,最明显的第一个调试步骤是“退后一步”并尝试检查您正在使用的变量。

举例说明:如果console.log(myThing.items[0].parent.nodeName)失败,您应该立即尝试console.log(myThing) —— 这允许您检查myThing变量,以便您可以手动验证路径是否是您'重新访问是合法的。 所有经验水平的开发人员最常犯的错误之一是他们放入了错误的数据路径,仅仅是因为犯错是人之常情。 (Typescript 将帮助您在编写代码时注意到这一点,但您必须学习如何在没有工具帮助的情况下跟踪问题,否则您将始终需要该工具。)

第三:正如我在本文初稿中提到的,您遗漏了一些return声明。

最重要的是,您的getFromSWAPI function 不会return任何内容。 如果您希望调用者接收数据,则必须return fetch

function getFromSWAPI() {
    return fetch("https://swapi.dev/api/people/1")
    // ...rest of chained thens

此外,您需要在调用updateInfo.then处理程序中返回一些内容。 您返回的内容取决于updateInfo的用途:

  • 如果updateInfo应该为了下游代码的利益而修改原始 API 数据,那么您应该返回调用它的结果:

     .then(function(data){ return updateInfo(data) })
  • 如果updateInfo应该引起某种副作用(比如用原始数据更新本地缓存,或触发事件等),那么您可能想“绕过”function:调用它,但转发原始值到下游代码:

     .then(function(data){ updateInfo(data) // could do _anything_ with data return data // passes the original data onward })

未经请求的代码审查

  • 您正在使用function关键字定义一个 function,并将另一个定义为常量箭头 function:

     function getFromSWAPI() { /* stuff */ } const updateInfo = responseJSON => { /* stuff */ }

    两种模式都可以正常工作,但您应该尽量保持一致。 我的建议:如果你还在学习 JS,更喜欢function关键字,因为它更明确。

  • 更喜欢使用异步/等待而不是链式处理程序

    您可以将函数定义为async ,然后await特定的异步操作。 在你的情况下, updateInfo似乎没有做任何异步工作,所以它必须存在于这个由三部分组成的链式 promise 中有点糟糕。我会 go 这个:

     async function getFromSWAPI() { let response = await fetch("https://swapi.dev/api/people/1") let data = await response.json() updateInfo(data) return data }

所以基本上你的代码中有一个小错误,

在这一行

{...}
.then(function (response) {
        return response.json()
    })
{...}

您已经返回 json,因此您将在下一行访问它

{...}
.then(function (data) {
        updateInfo(data)
    })
{...}

由于返回的数据本身就是真实数据,因此您不必在此处使用 data 属性重新访问它

{...}
const updateInfo = responseJSON => {
    console.log(responseJSON.data)
    let keys = Object.keys(responseJSON.data)
    console.log(keys)
}

完成的代码将如下所示 -

 function getFromSWAPI() {

    fetch("https://swapi.dev/api/people/1")
    .then(function (response) {
        return response.json()
    })
    .then(function(data){
        updateInfo(data)
    })
    .catch(function(err) {
        console.warn(err)
    })
}

const updateInfo = responseJSON => {
    console.log(responseJSON)
    let keys = Object.keys(responseJSON)
    console.log(keys)
}

或者,如果您在 function 中使用 fetch,我建议您使用 async/await。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM