【问题标题】:componentDidMount multiple fetch calls best practice?componentDidMount 多个 fetch 调用最佳实践?
【发布时间】:2019-03-23 18:53:33
【问题描述】:

我有很多相互独立的 api,需要在渲染之前存储在 React 状态中。我在componentDidMount 中有fetch 电话,但我不确定解决此问题的最佳方法是什么。 我是不是该... 1. 有嵌套的 fetch 调用

示例:

componentDidMount() {
    fetch('url')
    .then((res) => res.json())
    .then((data) => {
        // call another fetch in here
    })

}

或 2. 有单独的 fetch 调用

示例:

componentDidMount() {
    fetch('url')
    .then((res) => res.json())
    .then((data) => {
        // set state in here
    })

    // call another fetch for the other url endpoint
    fetch('url2')
    .then((res) => res.json())
    .then((data) => {
        // set state in here
    })
}

我不确定一种方法是否被认为比另一种更好,但我很想知道你们的想法以及一些优点/缺点是什么。

更新:我现在正在使用 Promise.all(),但我得到的是返回的 Promise 而不是实际值。这是我的代码:

Promise.all([
  fetch(`/api/url1`),
  fetch(`/api/url2`),
])
.then(([res1, res2]) => (
  {
    res1: res1.json(),
    res2: res2.json(),
}))
.then(({res1, res2}) => {
  this.setState({
    state1: res1,
    state2: res2,
  });
})
.catch((error) => {
  console.log(error);
});

当我在控制台上检查我的状态值时,我得到了以下信息:

Promise
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: Array(6530)

知道我可能遗漏了什么/做错了什么吗?

谢谢!

【问题讨论】:

  • 如果它们不相互依赖,绝对不要嵌套它们。使用Promise.all 渲染一次 而不是两次
  • 我正在使用 Promise.all(),但在我的 .then() 函数中,与承诺值(在我的例子中为对象数组)相比,我得到了返回的实际承诺。知道我可能做错了什么吗?我还用我的新代码更新了我的帖子。

标签: javascript reactjs api fetch


【解决方案1】:

fetch 返回Promise 而言,您可以使用Promise.all 函数并行执行两个提取:

componentDidMount() {
    Promise.all([fetch('url'), fetch('url2')])

      .then(([res1, res2]) => { 
         return Promise.all([res1.json(), res2.json()]) 
      })
      .then(([res1, res2]) => {
        // set state in here
      });
}

【讨论】:

  • 太棒了!只是想知道,如果我不使用 fetch() 方法,这也适用于 axios 吗?
  • 嘿!所以我认为它似乎正在工作,但是在第二个 .then() 方法中,我得到的是返回的承诺,而不是实际的数据。我做错了吗?
  • @kennycodes 我忘了response.json() 也会返回Promise。我已经编辑了我的答案。现在它应该可以工作了
【解决方案2】:

正如@CertainPerformance 提到的,您应该使用Promise.all 方法。

Promise.all([
  fetch("url1"),
  fetch("url2"),
  fetch("url3"),
]).then(([res1, res2, res3]) => {
  this.setState({status: "fetched"})
})

const url = "https://asdqwe.free.beeceptor.com/my/api/path";

const promises = Promise.all([
  fetch(url),
  fetch(url),
  fetch(url),
]);


promises
  .then((results) => 
    Promise.all(results.map(r => r.text()))
  )
  .then(console.log)

【讨论】:

  • 我正在使用与您的方法类似的方法,但我得到的是返回的实际 Promise 而不是值。我已经用我的新代码更新了我原来的帖子!
  • 我已将 sn-p 添加到我的原始答案中,我认为它应该有助于理解。
猜你喜欢
  • 2023-02-19
  • 2013-07-17
  • 1970-01-01
  • 2018-04-28
  • 1970-01-01
  • 1970-01-01
  • 2016-03-27
  • 2011-11-29
  • 2019-04-25
相关资源
最近更新 更多