Javascript однопоточный, и все операции DOM блокируются. Это означает, что если браузер занят добавлением и обновлением DOM, это заблокирует поток Javascript до тех пор, пока DOM не будет обновлен. Во время фактического обновления вы ничего не можете сделать в коде.
Это предполагает, что блокировка пользовательского интерфейса на самом деле связана с сырым, очень большим количеством манипуляций с DOM, а не с каким-либо другим основным виновником. Комментарий @ zerkms также точен, что анимированные gif, анимации CSS и т. д., как правило, не запускаются, когда браузер заблокирован, выполняя большие вычисления.
Если вы ожидаете блокировки браузера, самым простым решением будет показать некоторый оверлей spinner, , затем запустите команду, которая обновит ваши данные. Таким образом, счетчик уже будет в DOM. Когда обновление завершено, вы можете удалить счетчик. Это может выглядеть как
render() {
return <div>
<div onClick={ this.performLongRunningAction }>click me</div>
{ this.state.spinnerVisible ? 'Loading' : null }
</div>
}
performLongRunningAction() {
// First show the spinner...
this.setState({ spinnerVisible: true },() => {
// Then after state has been set and spinner rendered, start the
// long action
executeLongRunningActionNow();
});
}
// Then you need some mechanism to turn off the spinner state after the
// task has completed
componentWillReceiveProps(nextProps) {
// Did a task execute? Turn off the spinner before the next render
if(nextProps.someCompletedFlag !== this.props.someCompletedFlag) {
this.setState({ spinnerVisible: false });
}
}
Другим решением является разбить обновление на куски, так что вы обновить DOM в интервалах, которые являются достаточно минимальными, чтобы не запереть нить Javascript. Вы предоставили код, поэтому исключить это решение невозможно.
Если браузер занят выполнением операций DOM (или оценки JS в целом) - счетчик не будет анимировать. – zerkms
Правильно, я, как правило, забываю эту часть. Тем не менее, поскольку @ Andy-Ray предлагает, чтобы я мог что-то показать, например, «пожалуйста, подождите» без spinner и удалите его после фактического обновления DOM, если бы я имел в виду, когда DOM наконец обновляется. Но я не могу понять, как это сделать. Если я не сделаю что-то уродливое, например, опрос/setTimeOut, чтобы проверить, изменилась ли DOM. –