如何在 React 中停止循环直到异步操作完成?



我有一个组件,里面我正在与API通信(这里我把超时放在模拟上(。我在循环内部进行了一些调用,以更新当前交互索引上的数组。实际上,我想控制台.log所有带有添加数据的数组。这就是问题所在。Loop 正在经历所有迭代,并且不会等待完成异步任务,因此它会打印带有注释的空数组,说明有数据,但现在才刚刚出现。

我试图添加useState,但没有解决问题。

import React, {useEffect} from 'react';
function Ingredients() {
const heatingStepsTime = [];
const heatingStepsTimer = [];
function getTimes(i, type) {
if (type === "time") {
setTimeout(() => {
heatingStepsTime[i] = i;
}, 1000);
} else {
setTimeout(() => {
heatingStepsTimer[i] = i + 1;
}, 1000)
}
}
const getProcess = () => {
for (let i = 0; i < 3; i++) {
getTimes(i, "time");
getTimes(i, "timer");
}
};
useEffect(getProcess, []);
console.log(heatingStepsTime);
console.log(heatingStepsTimer);
return (
<div className="App">
test
</div>
);
}
export default Ingredients;

有没有办法在 React 中停止循环迭代,以便在非同步任务完成时继续?

试试这个

function App() {
function getTimes(i) {
return new Promise(resolve => {
setTimeout(() => {
resolve(i);
}, 1000);
});
}
const [heatingStepsTime, setHeatingStepsTime] = useState([]);
const getProcess = () => {
const promises = '0'.repeat(10).split('').map((c, i)=>getTimes(i));
Promise.all(promises)
.then(result=> setHeatingStepsTime(result));
};
useEffect(getProcess, []);
return (
<div className="App">
{heatingStepsTime.map((p,i)=><div key={i}>{p}</div>)}
</div>
);
}

https://stackblitz.com/edit/react-szrhwk

解释:

function getTimes(i) {
return new Promise(resolve => {
setTimeout(() => {
resolve(i);
}, 1000);
});
}

若要模拟 API,应使用 promise 对其进行模拟。此计时器将在超时时解析承诺。

const [heatingStepsTime, setHeatingStepsTime] = useState([]);

您希望将结果存储到一种状态中,以便 react 知道渲染结果

'0'.repeat(10).split('')

这只是为了模拟您的 for 循环...如果您有多个 API 调用,则可以忽略这一点...只需将其替换为

const promises = [apiCall1(), apiCall2()];
Promise.all(promises)
.then(result=> setHeatingStepsTime(result));

这将等待所有承诺解析并将结果存储到状态中

我找到了解决方案。在 React 中,我们需要使用 useState 在所有迭代中正确更新数组。这是固定代码 - 也许有人会遇到类似的问题,所以这里是解决方案:

import React, {useState, useEffect} from 'react';
function Ingredients() {
const [heatingStepsTime, setTime] = useState([]);
const [heatingStepsTimer, setTimer] = useState([]);
function getTimes(i, type) {
if (type === "time") {
setTimeout(() => {
setTime(currentTime => currentTime.concat(i))
},1000);
} else {
setTimeout(() => {
setTimer(currentTime => currentTime.concat(i))
}, 1000)
}
};
const getProcess = () => {
for (let i = 0; i < 3; i++) {
getTimes(i, "time");
getTimes(i, "timer");
}
}
useEffect(getProcess, []);
console.log(heatingStepsTime);
console.log(heatingStepsTimer);
if (heatingStepsTime[2] && heatingStepsTimer[2] && heatingStepsTime[2] === heatingStepsTimer[2]) {
console.log("Works!", heatingStepsTime[1], heatingStepsTimer[1])
}
return (
<div className="App">
test
</div>
);
}
export default Ingredients;

相关内容

  • 没有找到相关文章

最新更新