【问题标题】:Re-calling an async function in useEffect inside of another async function after a failed api fetching request在 api 获取请求失败后,在另一个异步函数内部重新调用 useEffect 中的异步函数
【发布时间】:2020-07-10 08:00:00
【问题描述】:

这有点难以解释,但这是我正在做的事情:

  1. 尝试从名为 getJsonData() 的异步函数中获取 json 数据,直到获取数据为止。
  2. 正确获取数据后,想从getOtherJsonData()获取另一组json数据

以下代码即使在 X 次失败后也能正确获取第一组数据 (getJsonData)。 (如果有的话)

但它不会一直获取第二组数据 (getOtherJsonData),因为可能会发生错误。我希望继续重新执行下面标记的代码块,直到正确返回第二组数据。

...
import React, {useState, useEffect} from 'react';
import {getJsonData} from './getJsonData';
imoport {getOtherJsonData} from './getOtherJsonData';

const myApp = () => {
    const [errorFetchedChecker, setErrorFetchedChecker] = useState(false);
    const [isLoading,setIsLoading] = useState(true);
    const [data,setData] = useState(null);

    const updateState = jsonData => {
      setIsloading(false);
      setData(jsonData);
    };

    useEffect(() => {
      getJsonData().then(
        data => {
          updateState(data);

          // This is the bloc I want to keep re-executing
          //
          getOtherJsonData(data.title).then(
            otherData => {
              updateOtherState(otherData);
              console.log("Updated with no error);
            },
            otherError => {
            console.log("Error, try getOtherJsonData again ?");
            console.log("Can't try to refresh, no errorFetchedChecker for me :/ ");
            }
          //
          // Until It doesn't return an error

        },
        error => {
          console.log('Error fetching, re-trying to fetch thanks to errorFetchedChecker');
          setErrorFetchedChecker(c => !c);
        },
      );
    }, [errorFetchedChecker]);

    return (
      <View>
        <Text>{state.data.title}</Text>
        <Text>{data.data.completed}</Text>
      </View>
    );
}

这里是getJsonData()和getOtherJsonData()

export async function getJsonData() {
  try {
    let response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
    let responseJson = await response.json();
    return responseJson;
  } catch (error) {
    throw error;
    // Should I just throw the error here ?
  }
}

export async function getOtherJsonData(oldData) {
  try {
    let response = await fetch(`https://someOtherApilink/${oldData}`);
    let responseJson = await response.json();
    return responseJson;
  } catch (error) {
    throw error;
    // Should I just throw the error here also ?
  }
}

This 是我的另一个问题,它解释了如何在失败的情况下重新执行第一个 getJsonData()。

以下是我尝试过的,但给了我关于未处理承诺的错误:

const subFunction(myTitle) => {
  getOtherJsonData(myTitle).then(
    otherData => {
      updateOtherState(otherData);
      console.log("Updated with no error);
    },
    otherError => {
      console.log("Error, try getOtherJsonData again!");
      subFunction(myTitle);  //Gives Unhandled promise warning and no result
    }
}

useEffect(() => {
  getJsonData().then(
    data => {
      updateState(data);

      // This is the bloc I want to keep re-executing
      //
      subFunction(data.title);
      //
      // Until It doesn't return an error

    },
    error => {
      console.log('Error fetching, re-trying to fetch thanks to errorFetchedChecker');
      setErrorFetchedChecker(c => !c);
    },
  );
}, [errorFetchedChecker]);

注意:请随意以任何方式、形状或形式重新表述标题。

【问题讨论】:

  • 我只是想仔细检查一下,这是您的原始代码吗?它有几个未终止的字符串。
  • 整体代码相同,只是删除了一部分并重命名以避免混淆。

标签: reactjs react-native fetch-api use-effect


【解决方案1】:

您可以尝试使用两个useEffect 将这两个函数分开,因为现在您必须重复第一个请求以防第二次失败。像这样的:

useEffect(() => {
      getJsonData().then(
        data => {
          updateState(data);
        },
        error => {
          console.log('Error fetching, re-trying to fetch thanks to errorFetchedChecker');
          setErrorFetchedChecker(c => !c);
        },
      );
    }, [errorFetchedChecker]);

useEffect(() => {
    // prevent request if there's no data
    if (data) {
        getOtherJsonData(data.title).then(
            otherData => {
              updateOtherState(otherData);
              console.log("Updated with no error);
            },
            otherError => {
            console.log("Error, try getOtherJsonData again ?");
            console.log("Can't try to refresh, no errorFetchedChecker for me :/ ");
            // you'll have to create one more state for that
            setOtherErrorFetchedChecker(c => !c);
            }
    }
}, [data, otherErrorFetchedChecker])

【讨论】:

  • 工作流畅,谢谢!快速提问:您如何建议尝试获取数据 X 次而不是无限期地获取数据?
  • @AnisBenna 您可以将otherErrorFetchedChecker 设为整数而不是布尔值。默认设置为零。因此,例如,您的 if 语句可以是 if (data &amp;&amp; otherErrorFetchedChecker &lt; 5)。如果请求失败setOtherErrorFetchedChecker(c =&gt; c++)
猜你喜欢
  • 1970-01-01
  • 2018-09-06
  • 1970-01-01
  • 2015-11-29
  • 2018-04-06
  • 1970-01-01
  • 1970-01-01
  • 2020-07-07
  • 2020-09-18
相关资源
最近更新 更多