【问题标题】:API Query fetch works, doesn't return result thoughAPI Query fetch 有效,但不返回结果
【发布时间】:2021-12-20 22:23:56
【问题描述】:

我正在尝试从 API useEffect 中获取值:

useEffect(async() => {
    try {
      const result  = await getToken(urlSuffix);
      logger.log('returned')
      setToken(result);
    } catch (error) {
      logger.debug('ERROR: ', error);
      throw error;
    }
  }, [urlSuffix]);

问题是,该函数永远不会返回令牌,但获取部分可以正常工作(我正在记录令牌)。这是 api 获取:

export const getToken = async (
  urlSuffix
) => {
  try {
    const url = `https://api_url/api/v1/asset/${urlSuffix}`;
    const data = await fetch(url, {
      headers: {
        'Accept': 'application/json',
        'X-Api-Key': API_KEY,
      },
      method: 'get',
      timeout: 5000, // 5 secs
    });

    const token = data?.data?.collection?.token;

    logger.debug('TOKEN: ', token);

    return token;
  } catch (error) {
    logger.debug('TOKEN FETCH ERROR');
  }
};

获取时的logger.debug 记录了正确的令牌,但useEffect 中的logger.log 从不记录结果已返回。是什么阻止了getToken 返回token

【问题讨论】:

  • 尝试在const result = await getToken(urlSuffix); 之前添加logger.log('calling');。在我看来,您一定是从其他地方致电getToken()
  • @RockySims 你是对的。这没有被调用,但我只是 CMD+F 搜索了我的整个项目,这是调用 api fetch 查询的唯一地方。这怎么可能?
  • 尝试在logger.debug('TOKEN: ', token); 之后添加throw 'wtf';,然后在浏览器控制台中,您可以查看错误以查看堆栈跟踪,它会告诉您从哪里调用getToken()。跨度>

标签: javascript fetch-api use-effect


【解决方案1】:

您似乎在使用fetch(),就好像它是Axios,但实际上并非如此。

fetch() 返回一个用没有data 属性的Response 对象解析的承诺。我认为您在getToken() 函数中想要的是这个......

export const getToken = async (urlSuffix) => {
  const url = `https://api_url/api/v1/asset/${urlSuffix}`;

  // FYI - fetch does not support timeouts
  const res = await fetch(url, {
    headers: {
      'Accept': 'application/json',
      'X-Api-Key': API_KEY,
    },
    method: 'GET',
  });

  if (!res.ok) {
    logger.debug('TOKEN FETCH ERROR');
    throw new Error(`${res.status}: ${await res.text()}`)
  }

  const data = await res.json() // parse the response stream as JSON
  const token = data.collection.token;

  logger.debug('TOKEN: ', token);

  return token;
}

您也不应该将异步函数传递给useEffect,因为它会破坏cleanup process

useEffect(() => {
  getToken(urlSuffix).then(setToken)
}, [ urlSuffix ]);

【讨论】:

    【解决方案2】:

    请注意,在 useEffect 内部使用 try...catch 是一种不好的做法 (see here)。

    但在我看来,您正确设置了async/await,所以它确实应该可以工作。

    尝试将 getToken 函数添加到 useEffect 挂钩的依赖项中。

    useEffect(async() => {
        try {
          const result  = await getToken(urlSuffix);
          logger.log('returned')
          setToken(result);
        } catch (error) {
          logger.debug('ERROR: ', error);
          throw error;
        }
      }, [urlSuffix, getToken]);

    【讨论】:

    • 取出 try catch 解决了我的问题。
    • 我认为您错过了您链接的帖子的重点。 try..catch 不是问题,为 useEffect 回调使用异步函数是
    • @kalculated 删除try..catch 确实无法解决您的问题
    • @Phil 我还更改了所有使用异步函数的 useEffects - 感谢您的回答和帮助我改进!
    猜你喜欢
    • 1970-01-01
    • 2013-08-13
    • 2023-03-19
    • 2021-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多