Ошибка браузера?Невозможно отобразить индикатор занятости, если не используется в течение не менее 20 мс - PullRequest
0 голосов
/ 25 сентября 2019

Проблема, с которой я столкнулся, заключается в том, что браузер не всегда показывает индикатор «занят», когда он должен.

Код ниже - это TypeScript, но это, конечно, просто JavaScript.Это использует кендо, но другие вызовы браузера тоже не работают.Я попытался просто показать gif занятости, плагин занятости jQuery, даже просто добавил небольшой текст в html.

  private demo() { 
     let that = this;
     this.slowOperation(function () {
        that.cpuIntensiveCode();
     }, 20); // < 20 fails to show busy; >= 20 works, but > 50 is better
  }

  private slowOperation(fun: any, ms: number) {
     kendo.ui.progress($(".spinner"), true);
     setTimeout(() => this.callback(fun), ms);
  }

  private callback(fun: any) {
     fun();
     kendo.ui.progress($(".spinner"), false);
  }

Если я установил значение ms в 0, индикатор занятости не отображается, хотятак должно быть.Это какая-то ошибка браузера (Chrome / Firefox)?«slowOperation» возвращает текущий поток, поэтому у браузера была возможность обновить отображение до вызова «обратного вызова», но по какой-то причине он этого не делает.

Как отобразить «занято»индикатор, пока не заставит небольшой период ничего не делать?Эта задержка заметна;на самом деле в cpuIntensiveCode присутствует большая изменчивость (мой пользовательский интерфейс имеет большое количество пользовательских выборок и комбинаций), и он может быть медленным или быстрым, поэтому я не хочу добавлять к нему 20 мс.Зная, сколько времени это займет, будет куча кода, который я тоже не хочу.Просто нужно, чтобы браузер делал то, что ему было сказано.

1 Ответ

1 голос
/ 25 сентября 2019

Поскольку существует только один поток, рендеринг

kendo.ui.progress($(".spinner"), true);

заблокирован, теоретически возможен / может быть обратный вызов этого метода, который обеспечит последующие вычисления после завершения рендеринга.

По сути, вы не можете ожидать, что рендеринг будет частью синхронного выполнения скрипта.Конечно, вы могли бы что-то приготовить с помощью requestAnimationFrame, но вместо этого предпочтение следует отдать обратному вызову из метода рендеринга или Web Worker.

То, о чем вы говорите за 20 миллисекунд, просто гарантирует, что рендеринг счетчика прогресса завершится до начала вычислений.

Я придумал тот же рабочий jsfiddle, который показывает, о чем вы говорите, и решение с Web Worker, которое будет выполнять код с интенсивным использованием ЦП в отдельном потоке.

https://jsfiddle.net/ivarprudnikov/g3uktx9d/

...