【问题标题】:Getting .json is not a function on Promise.all w/fetch获取 .json 不是 Promise.all w/fetch 上的功能
【发布时间】:2020-11-27 23:38:07
【问题描述】:

哦,我又一次遇到了那些 Promise.all 忧郁:(我有一个函数可以从提供的 url 中创建一个 fetch 调用数组,然后我们想通过 Promise.all 检索数据并返回响应数组或更好将承诺返回给调用函数。问题是这会导致控制台显示错误:

There was problem retrieving data. TypeError: r.json is not a function

函数的代码是:

 const getLeagueLeaders = (url, params) => {
  // First let's create the array of url's
  let queryURLs = [];

  params.forEach((param) => {
    queryURLs.push(
      fetch(`${url}${new URLSearchParams(param)}`, {
        method: "get",
        headers: {
          Authorization:
            "Basic ==",
        },
      }).then((res) => res.json())
    );
  });

  return (
    Promise.all(queryURLs)
      // map array of responses into an array of response.json() to read their content
      .then((responses) => responses.map((r) => r.json()))
      .catch((err) => {
        console.error("There was problem retrieving data.", err);
      })
  );
};
    
    module.exports = getLeagueLeaders;

在 Vue 组件中

 mounted: async function () {
        const leagueLeadersResponseArray = await getLeagueLeaders(
          this.fetchBaseUrl,
          this.params
        );
this.qbLeaders =
      leagueLeadersResponseArray[0].cumulativeplayerstats.playerstatsentry;

很明显,leagueLeadersResponseArray 是未定义的。我研究了 .json() 并没有看到我是如何错误地使用它的。起初我以为我需要一个 Promise.all 包装器,用于responses.map((r) => r.json()) 但这也没有好处。我看了这个link,但我没有像他那样使用 fetch。非常感谢任何指导......

为其他人更新了工作代码:

// ---------- src/js/modules/ ------------------ //

/* jshint ignore:start */
// Make function to retrieve League Leaders in a Category

const getLeagueLeaders = (url, params) => {
  // First let's create the array of url's
  let queryURLs = [];

  params.forEach((param) => {
    queryURLs.push(
      fetch(`${url}${new URLSearchParams(param)}`, {
        method: "get",
        headers: {
          Authorization:
            "Basic ==",
        },
      }).then((res) => res.json())
    );
  });

  return Promise.all(queryURLs).catch((err) => {
    console.error("There was problem retrieving data.", err);
  });
};

module.exports = getLeagueLeaders;

【问题讨论】:

  • fetch() 被视为字符串模板的一部分,而不是您想要的 JavaScript 函数。字符串没有函数.json()。调用实际的fetch 函数,而不用像fetch(`your string literal URL`, {/* your request config object */}) 这样的反引号括起来。此外,then(data => { return data }) 什么也不做。你需要 return Promise.all 代替,它返回一个承诺数组,这些承诺将在另一个 Promise.all 之后解析为 JSON。
  • 一个字符串没有.json方法 - 检查queryURLs数组的内容

标签: javascript fetch promise.all


【解决方案1】:

您的模板字符串在整个 fetch 周围,而它应该只在要获取的参数中:

  params.forEach((param) => {
    queryURLs.push(fetch(`${url}${new URLSearchParams(param)}`, {
      method: "get",
      headers: {
        Authorization:
          "Basic *****==",
      }
    }));
  });

然后,你有一个.then(data => {return data}),它不会做任何事情,因为returnthen 回调返回,不是函数。你应该返回 Promise.all 给你的承诺:

  return Promise.all(queryURLs)
    // map array of responses into an array of response.json() to read their content
    .then((responses) => responses.map((r) => r.json())) // Get error There was problem retrieving data. TypeError: r.json is not a function
    .catch((err) => {
      console.error("There was problem retrieving data.", err);
    });

【讨论】:

  • 谢谢!如何使用返回的数据。我以为 this.qbLeaders = LeagueLeadersResponseArray[0].cumulativeplayerstats.playerstatsentry;将使我能够访问 API 的第一个响应。但我知道它是未定义的。
  • 您应该console.log(leagueLeadersResponseArray) 以确保数据符合您的预期。
  • 现在我很困惑。我认为一旦 Promise.all 解决了,那么 LeagueLeadersResponseArray 就会将我的三个 reposnses 作为每个文档的数组包含在其中。相反,我有这个:这是返回 LeagueLeaders 数组 [object Promise]、[object Promise]、[object Promise]。任何建议。
  • 哦,您可能想将queryURLs.push(fetch(...)) 更改为queryURLs.push(fetch(...).then((res) => res.json()),它会起作用。
  • 查看更新的代码。现在我们回到检索数据时出现问题。 TypeError: r.json 不是函数错误。 ???
猜你喜欢
  • 1970-01-01
  • 2022-08-17
  • 2017-10-18
  • 1970-01-01
  • 2021-12-13
  • 2017-11-15
  • 2019-05-16
  • 2018-07-24
  • 2020-09-20
相关资源
最近更新 更多