gpt4 book ai didi

javascript - 使用 setState 响应计算密集型函数的更新进度

转载 作者:行者123 更新时间:2023-12-03 14:43:03 26 4
gpt4 key购买 nike

我有一个简单的 React 类显示 this.state.progress (一个数字),这个状态可以通过 updateProgress(progress) 更新功能。

class App extends React.Component {
constructor(props) {
super(props);
this.state = {
progress: 0,
}
}

updateProgress = (progress) => {this.setState({progress}); };
render() {
let {progress} = this.state;
return <h1>{progress}</h1>;
}
}

我有一个计算密集型函数 myHeavyFunc ,为此我需要显示进度条。我调用 updateProgress我上面提到的函数使用 myHeavyFunc 中的循环变量.

myHeavyFunc = async (updateProgress) => {
let loopLength = 1000000;
updateProgress(0);
for(let i=0; i<loopLength; i++) {
// some processing happens here
updateProgress((i+1)/loopLength);
}
}

发生的情况是状态得到更新,我可以通过控制台在 setState 中记录进度来确认这一点。回调,但组件直到最后才会重新渲染。但是,如果我包含一个小的 sleep 1ms,然后重新渲染发生,进度更新(显然时间上的巨大损失,我不喜欢)。

JSFiddle here .我在这里运行 myHeavyFunc单击进度编号。你可以看到当 await sleep(1)评论, onClick在一秒钟内完成,但不显示进度。它甚至不会因任何后续点击而改变。另一方面,如果没有评论,我会得到进度更新,但它只需要很长时间才能完成!

我知道 React 应该 batch出于性能原因进行更新,但就我而言,在整个循环完成之前,我什至看不到一次更新。另外,请注意我不是在寻找 synchronous setState功能,但我需要在设置状态后重新渲染(至少仅在进度元素上)。如果它由于批处理而丢失了一些进度更新,我很好,但我确实希望它能够显示进度。

有没有办法运行 myHeavyFunc以非阻塞方式更新 UI 中的进度? 在 React 中更新计算密集型函数进度的正确方法是什么?

最佳答案

我建议您尽可能少地通知进度。进度会从 0 到 100,所以我只会通知进度 100 次,并且我会添加一个超时,所以用户可以看到进度转换:
如果循环长度 = 1000000,
1000000/100 = 10000
每 10000 次迭代我将调用 updateProgress 函数。

let myHeavyFunc = async (updateProgress) => {
let loopLength = 1000000;
let current = 0;
for(let i=0; i<loopLength; i++) {
const result = Math.floor(((i+1)/loopLength)*100);
if(current != result) {
setTimeout(()=> {
updateProgress(result);
}, result *100);
}
current = result;
}
}
见: https://jsfiddle.net/wbzx4j90/1/

关于javascript - 使用 setState 响应计算密集型函数的更新进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58378963/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com