javascript - 让 React 在长时间运行的任务之间渲染页面

标签 javascript reactjs async-await es6-promise

我在 Javascript 中有一个长时间运行的任务。 React 应该在任务之间的几个点上重新渲染组件。但它仅在整个任务结束时才重新呈现。如何让 React 在所有 setState() 调用时重新呈现页面?

一个简化的例子:

setStatePromise = (state) => new Promise(resolve => {
    this.setState(state, () => resolve());
});
longRunningTask = async () => {
    await this.setStatePromise({progress: 1}); // not shown to the user
    await doMuchWork();
    await this.setStatePromise({progress: 2}); // not shown to the user
    await doEvenMoreWork();
    await this.setStatePromise({progress: 3}); // shown to the user when everything is done
};
onButtonClick = async () => {
    await this.longRunningTask();
}

这是一个显示问题的工作示例:

https://codesandbox.io/s/intelligent-cori-31qn5

我之前使用的解决方法是:

setStatePromise = (state) => new Promise(resolve => {
    this.setState(state, () => {
        setTimeout(() => resolve(), 1);
    });
});

最佳答案

不断调用“Render”方法。 问题是因为 Javascript 是单线程的。

doMuchWork 内部的循环正在阻塞主线程(以及 UI)。

How to do a loop in Javascript that doesn't block the UI?

解决该问题的一种快速方法是将 doMuchWork 中的算法(如果可能)拆分为步骤/ block :https://codesandbox.io/embed/nostalgic-wiles-g38ce , 但它有很多缺点。

setTimeout 允许其他方法等完成它们的工作(如刷新 UI),将回调放在队列的后面,这就是为什么本主题中给出的 setTimeout(..., 1000) 解决方案效果很好。

其他(更好的)方法是使用建议的生成器或使用专门为完成此类耗时工作而创建的 Web Worker。

Something about your problem with a solution using Web Workers .

关于javascript - 让 React 在长时间运行的任务之间渲染页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57724713/

相关文章:

javascript - 如何防止 jQuery onclick 事件中的 Ruby 方法在页面刷新时执行

javascript - 在 javascript 中使用从 C# 返回的数据结构

javascript - Protractor - MouseMove 不支持 Firefox

javascript - 创建 React 函数组件时,使用粗箭头函数还是常规 ES5 函数更好?

c# - Parallel.ForEach 中的多个异步等待链接

c# - 运行异步 lambda 时,使用 Task.Run(func) 还是 new Func<Task>(func)()?

php - 只显示部分谷歌地图

javascript - 如何使用 React 获取传播运算符更新状态

javascript - 如何有效地将数据存储在数组中?

node.js - 具有异步/等待的 Node - 如何获取发生错误的特定行?