无法使用 GET 方法获取 JSON 数据:res[​​=10=] 未定义错误

Cannot fetch JSON data using GET method: resJSON is not defined error

我正在尝试使用此获取函数从后端服务器获取数据:

 let users = []
  const fetchUsers = () => {
    fetch(baseUrl + "/users/", {
      method: "GET",
    })
      .then((res) => res.json())
      .then((data) => (resJSON = data))
      .then((resJSON) => {
          users = resJSON;
      })
      .catch((err) => {
        console.log("error in json", err);
        users = [];

      });
  };

但是我明白了

error in json ReferenceError: resJSON is not defined

此行发生错误:.then((data) => (resJSON = data))

奇怪的是,我在后端看到创建了 json。此外,我在另一个端点上对 POST 数据使用非常相似的提取请求,没有任何问题。所以我想知道这里可能出了什么问题?

您的 return 语句中有一个赋值。此外,此分配的范围仅限于当前回调,因此在下一个 .then 块中,resJSON 不可用。也不需要尝试做额外的作业。

let users = []
fetch(/* ... */)
   .then((res) => {
        // res is the raw response.
        // res.json returns a new promise
        // that when sucefully fulfilled, 
        // will return the decoded body
        return res.json()
    })
   .then((data) => {
     // data refers to the json decoded 
     // bytes of the response body
     // assign it directly to user
     users = data
   })
   .catch(console.warn)

这可能仍然存在问题,因为您永远不知道用户何时分配或不分配。根据您的代码,您应该将额外的工作转移到回调本身。

const useUserdata = (users) => 
    console.log("do something with the user", users)

fetch(/* ... */)
   .then(raw => raw.json())
   .then(useUserdata)
   .catch(console.warn)

问题是 resJSON = data 正在分配给未在任何地方声明的标识符。显然你的代码是 运行 在严格模式下(很好!),所以分配给一个未声明的标识符是一个错误。

但不需要 resJSON,它在该代码中没有做任何有用的事情。您可以组合两个 then 处理程序并执行 users = data但是,这通常是不好的做法,因为您正在为 this problem where you try to use users before it's filled in. (Your code is also falling prey to the fetch API footgun I describe in this post on my anemic old blog 做准备:您需要在调用 json() 之前检查 ok。)

但从根本上说,将 fetchUsers 直接分配给在其外部声明的 users 变量是自找麻烦。相反,让 fetchUsers return 用户数组的承诺。在 2022 年,您可以使用 async 函数来做到这一点:

const fetchUsers = async () => {
    const response = await fetch(baseUrl + "/users/", {
        method: "GET",
    });
    if (!response.ok) {
        throw new Error(`HTTP error ${response.status}`);
    }
    return await response.json();
};

(如果你想隐藏调用代码中的错误(这是不好的做法),请将其包装在 try/catch 和 return 中的空数组中 catch.)

然后让需要填写的代码 userslet users = await fetchUser(); (注意,代码也需要在 async 函数中,或者在顶层一个模块)。

如果由于某种原因您不能使用 async 函数,您可以使用旧方法:

const fetchUsers = () => {
    return fetch(baseUrl + "/users/", {
        method: "GET",
    })
    .then(response => {
        if (!response.ok) {
            throw new Error(`HTTP error ${response.status}`);
        }
        return response.json();
    });
};