异步函数带有诺言。所有人仅在更新代码后运行
我正在编写反应中的异步功能,该功能应将“坐标”状态设置为包含美国州及其各自纬度/纵向的对象。为此,我正在使用Promise.All进行API呼叫并解决这些呼叫。在页面的第一个更新中,该功能按预期工作。但是,在随后的刷新中,该函数不会执行承诺。所有声明,因此没有设置坐标状态。为什么这种情况?如何解决这个问题?
export default function App() {
const [covidDataJSON, setCovidDataJSON] = useState(null);
const [stateNames, setStateNames] = useState([]);
const [coords, setCoords] = useState([]);
const [stateInfos, setStateInfos] = useState([]);
useEffect(() => {
fetchCoords();
}, [])
const fetchCoords = async () => {
try {
getStateNames();
const req = await Promise.all(stateNames.map(async (state) => {
return await axios.get(`https://nominatim.geocoding.ai/search.php?state=${state}&format=jsonv2`);
}))
for (let i = 0; i < req.length; i++){
const stateInfo = req[i].data[0];
if (req[i].data.length !== 0)
setCoords(coordsArr => [...coordsArr, {name: stateInfo.display_name, lat: stateInfo.lat, lon: stateInfo.lon}]);
}
} catch (err) {
console.error(err);
}
};
const getStateNames = () => {
try {
const stateArr = [];
for (let i = 0; i < states.length; i++){
stateArr.push(states[i].name);
}
setStateNames(stateArr);
} catch (error) {
console.error(error);
}
}
I'm writing an asynchronous function in React that should set the "coords" state to an array of objects containing US states and their respective latitudes/longitudes. To do this, I'm making an API call and resolving those calls using Promise.all. On the first refresh of the page, the function works as intended. However, on subsequent refreshes, the function does not execute the Promise.all statement and therefore does not set the coords state. Why is this the case and how can I resolve this issue?
export default function App() {
const [covidDataJSON, setCovidDataJSON] = useState(null);
const [stateNames, setStateNames] = useState([]);
const [coords, setCoords] = useState([]);
const [stateInfos, setStateInfos] = useState([]);
useEffect(() => {
fetchCoords();
}, [])
const fetchCoords = async () => {
try {
getStateNames();
const req = await Promise.all(stateNames.map(async (state) => {
return await axios.get(`https://nominatim.geocoding.ai/search.php?state=${state}&format=jsonv2`);
}))
for (let i = 0; i < req.length; i++){
const stateInfo = req[i].data[0];
if (req[i].data.length !== 0)
setCoords(coordsArr => [...coordsArr, {name: stateInfo.display_name, lat: stateInfo.lat, lon: stateInfo.lon}]);
}
} catch (err) {
console.error(err);
}
};
const getStateNames = () => {
try {
const stateArr = [];
for (let i = 0; i < states.length; i++){
stateArr.push(states[i].name);
}
setStateNames(stateArr);
} catch (error) {
console.error(error);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为您的诺言。所有人都不执行,因为Statename仍然是一个空数组。
您需要定义2个使用效果挂钩如下。 -
此外,我看不到上述示例代码中定义的getStateNames中使用的状态变量。还要从fetchcoords()内部删除getStateNames()调用以上是否适合您,并尝试登录stateNames来验证这一点。
I think your promise.all does not execute because stateNames is still an empty array.
You need to define 2 useEffect hooks as follows. -
Also, I don't see the states variables used in getStateNames defined in above sample code. Also remove getStateNames() call from inside of fetchCoords() Let me know if the above works for you and try logging stateNames to verify this.
getStateNames()
,您正在调用setStateNames(statearr);
状态的设置器函数是异步。您正在映射fetchcoords()
内的statename。在运行地图循环时,stateNames
未更新状态可能性。这就是为什么我从getStateNames()
返回statearr
,然后在fetchcoords()
中使用该值。。内部
fetchcoords()
,您添加了以下代码因此无需
等待Axios.get()
在这里等待承诺解决的原因,这就是为什么我从.map
中删除了等待Axios.get() > Promise.all()
尝试一下。我认为这应该有效。
Inside
getStateNames()
, you're callingsetStateNames(stateArr);
setter function for a state is async. You're mapping over stateNames insidefetchCoords()
. There is a possibility thatstateNames
state is not updated when map loop is run. Thats why I returnstateArr
fromgetStateNames()
and use that value insidefetchCoords()
.Inside
fetchCoords()
, you've added the following codeThere is no need to
await axios.get()
here because you're already usingPromise.all
to await for promises to resolve, that's why I've removedawait axios.get()
from.map
and simply returning an array of promises forPromise.all()
Give this a try. I think this should work.