Re-calling 在 api 获取请求失败后,另一个异步函数内的 useEffect 中的异步函数
Re-calling an async function in useEffect inside of another async function after a failed api fetching request
解释起来有点棘手,但我正在做的是:
- 尝试从名为 getJsonData() 的异步函数获取 json 数据,直到获取数据。
- 正确获取数据后,我想从getOtherJsonData()
获取另一组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])
解释起来有点棘手,但我正在做的是:
- 尝试从名为 getJsonData() 的异步函数获取 json 数据,直到获取数据。
- 正确获取数据后,我想从getOtherJsonData() 获取另一组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 ?
}
}
以下是我尝试过但给我关于未处理的承诺的错误:
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])