反应超时竞赛条件

时间:2018-11-24 05:09:16

标签: reactjs asynchronous

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需要取消该计时器,并立即使用存储的操作更新数据结构。我需要防止在不可预测的时间调用刷新。

从技术上讲,我可以直接修改状态以使其同步运行,但我不希望这样做。

2 个答案:

答案 0 :(得分:1)

setState(state,callback)为此存在重载:以确保状态更改后调用callback

话虽如此,您可以将updatePixelBuffer转换为返回Promise的内容,并在调用callback时进行解析。

此外,您还可以让triggerPixelRefresh还返回立即解决的诺言。

最后,将它们都包装在函数中,使函数公开triggerPixelRefreshPromise resolve方法,之后可以调用该方法。

最后,将两个承诺都包装在Promise.race([p1,p2])中。

Promise.race(p1,p2)所做的事情是,它将解决{problem}承诺中的第一个承诺(换句话说,超时或您的直接呼叫)。

也来看看这个: Understanding promise.race() usage

答案 1 :(得分:0)

在您要寻找的内容中使用回调钩子应该非常容易。因此,与其尝试通过在一个函数之后调用另一个函数来强制同步(,即使这在日常工作中仍然有效,但从技术上讲,仍然不能保证,因为OS / Runtime / Hardware可以决定在运行您的函数之前先参加一些更重要的工作下一个函数),因此我宁愿将>>> l = list(range(10)) >>> l [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> l[3] = 'foo' >>> l [0, 1, 2, 'foo', 4, 5, 6, 7, 8, 9] >>> l.insert(7, 'bar') >>> l [0, 1, 2, 'foo', 4, 5, 6, 'bar', 7, 8, 9] 作为triggerPixelRefresh的函数输入,这样您就可以更好地控制何时调用它。

updatePixelBuffer

那你就可以做

updatePixelBuffer(x, y,triggerRefreshHandler) {
...call triggerRefresherHandler at the appropriate time here
}

这可能不是很关键,但是我注意到您使用了很多窗口对象,我很好奇这是否不会引起任何问题,因为React使用虚拟DOM,并且SPA通常也会在服务器上运行您希望服务器呈现性能,并且在NodeJS之类的环境中不存在。

快乐编码

相关问题