reactjs - 反应超时竞争条件
问题描述
updatePixelBuffer(x, y) {
console.log("cleared from update", this.state.pixelRefreshTimer);
window.clearTimeout(this.state.pixelRefreshTimer);
let pixelRefreshTimer = window.setTimeout(() => {
console.log("from timer", pixelRefreshTimer);
this.triggerPixelRefresh();
}, 3000);
console.log("set timer", pixelRefreshTimer);
this.setState({
pixelRefreshTimer: pixelRefreshTimer,
});
// store operation in buffer and perform visual draw
}
triggerPixelRefresh() {
console.log("cleared from refresh", this.state.pixelRefreshTimer);
window.clearTimeout(this.state.pixelRefreshTimer);
// update data structure with operations in buffer
}
大多数情况下,updatePixelBuffer 会被多次调用,因为我使用它来存储绘图操作,然后在数据结构上批量更新它们,我允许用户实时可视化绘图操作(即使数据结构还没有更新)。
当我想在调用 updatePixelBuffer(x, y) 后立即调用 triggerPixelRefresh() 时,我的困境就开始了。计时器不应在此呼叫后启动。
updatePixelBuffer(1, 2);
triggerRefresh();
由于 setState 是异步的,所以我不知道如何保证 triggerPixelRefresh() 中的 window.clearTimeout 会在 updatePixelBuffer 中新设置的计时器被一个接一个地调用时清除它们。我不确定使用什么模式来保证这一点。
updatePixelRefresh 设置了一个计时器,以便如果以后不调用 triggerPixelRefresh,它将被调用。这是为了保证缓冲区中的操作是在以后进行的。triggerRefresh 需要取消该计时器并立即使用存储的操作更新数据结构。我需要防止在不可预测的时间调用刷新。
从技术上讲,我可以直接修改状态以使它们同步运行,但我不希望这样做。
解决方案
setState(state,callback)
为此存在重载:保证callback
在状态改变后被调用。
话虽如此,您可以将您的转换updatePixelBuffer
为返回一个在被调用Promise
时解析的。callback
此外,您triggerPixelRefresh
还可以返回一个立即解决的承诺。
最后,将它们都包装在函数中,让函数暴露triggerPixelRefreshPromise
解析方法,您可以在之后调用该方法。
最后,将两个 Promise 都包装在Promise.race([p1,p2])
.
所做Promise.race(p1,p2)
的是它将p1,p2
解决首先解决的任何一个承诺(换句话说,超时或您的直接调用)。