【问题标题】:Why my function is firing even though it is inside a .then chain (promise/async/await)?为什么我的函数即使在 .then 链(promise/async/await)中也会触发?
【发布时间】:2021-08-02 04:25:26
【问题描述】:

我很困惑为什么我的异步函数在运行内部代码之前不等待。然后

例如,卡片应该是一个包含 102 个元素的数组。但是,console.log(cards.length) 显示为 0。此外,最后一个 .then 在任何元素放入卡片之前都会被原谅。

  React.useEffect(() => {
    // if (!cards.length) {
    //https://api.pokemontcg.io/v2/cards?q=set.id:base1
    async function fetchCards() {
       const response = await fetch('https://api.pokemontcg.io/v2/cards?q=set.id:base1', {
        mode: 'cors',
        headers: {
          'X-Api-key': '22173ccf-376e-4d12-8d50-8b25df6a8e13',
        },
      })
        .then((res) => res.json())
        .then((data) => {
          console.log(data.data);
          setCards(data.data);
          console.log(cards.length);
        })
        .then(() => {
           updateDeck(getRandom(cards, 4));
        });
    }
    // }
    fetchCards()
  }, []);

【问题讨论】:

  • fetchCards 的主体不返回任何内容,因此第一个 .then() 已经没有数据可以使用。而不是const response = await fetch(...) 只是return fetch(...)。事实上,为什么还要有 fetchCards?只要有fetch(url, ...).then(response => response.json()).then(......),不需要声明和调用,你已经有了一个以fetch开头的promise链。
  • @Mike'Pomax'Kamermans 我编辑了代码,但它的长度仍然是 0。
  • cards 来自哪里?您的then 接受一个名为data 的参数,而不是cards,因此您没有显示所有代码,我也不会猜测其余部分的作用。 如果 setCards 是一个状态函数,那么是的,显然关联的cards 不会在下一行更新:它将在下一次渲染调用时更新,而不是之前。这就是 React 中状态更新的工作原理。
  • 原谅我的无知。你的意思是我应该像这样包装 (res.json()) 来返回它吗?
  • 卡片来自 useState 初始化 const [cards, setCards] = React.useState([]);

标签: javascript async-await promise


【解决方案1】:
  1. 您不应将async/awaits 与then 回调混为一谈。

  2. 使用新的useEffect 检查cards 何时更改为调用您的updateDeck 函数。 setCards 是一个异步进程,因此新状态在您设置后不会立即可用。这就是为什么当状态发生变化时需要额外的useEffect

这是一个简短的例子:

useEffect(() => {
  async function fetchCards() {
    const res = await fetch(url, params);
    const data = await res.json();
    setCards(data.data);
  }
  fetchCards();
}, []);

useEffect(() => {
  if (cards.length) updateDeck(getRandom(cards, 4));
}, [cards]);

【讨论】:

  • 我没想到!我会试试看。但是,我编辑了代码以删除等待/异步,只留下 .then。但是,仍然没有运气。任何想法为什么?
  • setCards 是异步的,因此新状态在设置后不会立即可用,这就是为什么在状态发生更改时需要额外的useEffect
  • 我是否也应该将我想在卡片上运行的任何功能放在第二个 useEffect 中?
  • @captain:仅供参考,我已经撤销了你的编辑。 Stack Overflow 与您可能使用过的其他论坛有点不同,因为它的目标是创建对其他人有用的问答页面;因此,一旦发布了答案,您就不应编辑您的问题以使其无效。 (我的意思是,如果答案是由于误解了您的问题,那么可以编辑问题以澄清;但如果问题是关于错误并且答案显示了如何修复它,那么您不应该编辑问题修复该错误并询问新问题。)
  • 第二个 useEffect 在第一次渲染时被调用并抛出错误,因为卡是空的!是否可以让它在没有条件的情况下等待?
猜你喜欢
  • 1970-01-01
  • 2019-12-14
  • 2018-03-27
  • 1970-01-01
  • 2021-12-07
  • 1970-01-01
  • 2019-08-17
  • 1970-01-01
  • 2021-11-13
相关资源
最近更新 更多