Как сохранить анимацию при выполнении интенсивных расчетов - PullRequest
17 голосов
/ 04 сентября 2011

У меня есть страница, которая выполняет интенсивные и длительные вычисления в Javascript.Я хотел бы иметь анимацию загрузки, чтобы сообщить пользователю о прогрессе.У меня есть анимированный GIF сейчас, но все окно браузера зависает (и GIF не воспроизводится), пока работает Javascript.Затем, когда это сделано, он размораживается.Расчеты должны выполняться на стороне клиента, поэтому они не могут быть выполнены на сервере.

Есть ли способ не дать Javascript заморозить страницу и остановить воспроизведение анимации во время выполнения расчетов?

Ответы [ 7 ]

12 голосов
/ 04 сентября 2011

Вы также можете использовать HTML5 webworkers ( Wikipedia ) для запуска долго выполняющихся сценариев в фоновом режиме. Это похоже на многопоточность для JavaScript.

Он будет работать в последних браузерах, кроме IE.

Найдена игра с использованием веб-разработчиков Проверьте

5 голосов
/ 04 сентября 2011

Вы можете разбить работу на маленькие кусочки и использовать setTimeout, чтобы начать следующую итерацию, когда первая завершится, таким образом браузер сможет обновить пользовательский интерфейс. (это потому, что браузер использует один единственный поток, поэтому, если он занят выполнением js, он не может делать другие вещи)

3 голосов
/ 04 сентября 2011

Обработка Javascript однопоточная, поэтому пока ваш код работает, никакой другой анимационный код не запустится.

Вам необходимо настроить обработку для запуска в пакетном режиме. Я не знаю, что вы обрабатываете, но если вы делаете что-то, что можно легко разделить, то вы можете обработать первые N элементов, а затем использовать setTimeout, чтобы запланировать запуск следующего фрагмента за несколько миллисекунд. Таким образом, вы даете браузеру время заняться другими делами, которые необходимо выполнить.

1 голос
/ 01 ноября 2016

Возможно, вам это больше не нужно, но на случай, если кто-то еще погуглит, вот еще одно простое решение:

* обратите внимание, что это будет работать только в том случае, если выполнение этого огромного скрипта вызвано длинным итерационным циклом

- сделайте вашу петлю примерно такой:

function AsyncLoop(i, lastLoop, parameters) {
        setTimeout(function () {
            if (i < lastLoop) {
                //whatever you wanna do here
                window.console.log('iteration ' + i + ': ' + parameters[i].whatevs);

                i++;
                AsyncLoop(i, lastLoop, parameters);
            }
        }, 0);
    }

- тогда назовите это как:

AsyncLoop(0, incredblyLongObjectArray.length, incredblyLongObjectArray);

Вот небольшая скрипка без использования параметров (чтобы их было легче понять) и с функцией, позволяющей определить, завершился ли желаемый сценарий:

https://jsfiddle.net/or1mrmer/

1 голос
/ 08 февраля 2015

CSS3-анимации обычно продолжают работать, даже если JavaScript блокирует (протестировано с Chrome 40.0).

Таким образом, вы можете использовать библиотеки, такие как SpinKit или spin.js , чтобы визуализировать, что вычисления продолжаются.

Однако обратите внимание на наличие анимации CSS3:
caniuse.com
Разгон Android-мифов об анимации CSS

1 голос
/ 04 сентября 2011

Если браузер зависает, это означает, что вы выполняете какую-то серьезную работу.

Единственный способ решить эту проблему - добавить 100 мс сна каждую секунду выполнения скрипта.Пожалуйста, посмотрите на javascript setInterval() call.

0 голосов
/ 16 ноября 2017

Я ответил на это функциональным примером (с простым индикатором прогресса) здесь .

Он использует «yield» и чрезвычайно прост в использовании (и изменяет существующие циклы JS), когда выпросто хотите разрешить другим процессам временной интервал, и его проще настроить, чем веб-работников (которые я также использовал), особенно если у вас уже есть цикл, взаимодействующий с глобальными переменными.

...