Re-calling 在 api 获取请求失败后,另一个异步函数内的 useEffect 中的异步函数

Re-calling an async function in useEffect inside of another async function after a failed api fetching request

解释起来有点棘手,但我正在做的是:

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

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

但是它不会一直获取第二组数据 (getOtherJsonData),因为可能会发生错误。我希望 保留 re-execution 下面标记的代码块,直到正确返回第二组数据。

...
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 ?
  }
}

是我的另一个问题,它解释了在失败的情况下如何 re-execute 第一个 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]);

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

您可以尝试使用两个 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])