Как сообщить о прогрессе функции JavaScript? - PullRequest
7 голосов
/ 07 апреля 2010

У меня есть функция JavaScript, которая довольно длинная и выполняет ряд задач, я хотел бы сообщать пользователю о прогрессе, обновляя содержимое элемента SPAN сообщением, когда я иду. Я попытался добавить document.getElementById ('spnProgress'). InnerText = ... операторы по всему коду функции.

Однако, пока функция выполняется, пользовательский интерфейс не будет обновляться, и поэтому вы всегда будете видеть только последнее сообщение, записанное в SPAN, что не очень полезно.

Мое текущее решение состоит в том, чтобы разбить задачу на несколько функций, в конце каждой я устанавливаю сообщение SPAN, а затем «запускаю» следующую с помощью вызова window.setTimeout с очень короткой задержкой (скажем, 10 мс ). Это дает контроль и позволяет браузеру перекрасить SPAN с обновленным сообщением перед началом следующего шага.

Однако я нахожу это очень грязным и трудным для понимания кода, я думаю, что должен быть лучший путь. У кого-нибудь есть предложения? Есть ли способ заставить SPAN перерисовать, не выходя из контекста функции?

Спасибо

Ответы [ 6 ]

7 голосов
/ 07 апреля 2010

То, как вы это делаете, является правильным (на данный момент, это может измениться, когда стандарты появятся и будут приняты [см. ответ Эндрю Эйлетта ], но пока не на какое-то время). Вы должны уступить таким образом, чтобы браузер мог обновлять свой интерфейс. Я обнаружил, что чем больше я так думаю, тем чище становятся вещи, но мои первые несколько попыток сделать это были действительно «грязными». Надеюсь, вы найдете то же самое, что привыкли к нему.

3 голосов
/ 07 апреля 2010

Если у вас есть контроль над целевым браузером, вы можете использовать рабочий поток HTML5 для работы в фоновом режиме.

2 голосов
/ 07 апреля 2010

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

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

https://github.com/jameswestgate/taskjs

0 голосов
/ 07 апреля 2010

Примерно так может работать, если работа вашей функции выполняется в цикле.Он проверяет количество прошедшего времени и обновляет индикатор выполнения, если прошло 1/2 секунды.(Пример не проверен. Возможно, вам придется немного поиграть с ним.)

0 голосов
/ 07 апреля 2010

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

var a = some_local_state();
runTasksWithProgress([
    function() {
        do_some_work(a);
        a = a + 1;
    },
    function() {
        do_some_other_work(a);
        a = a * 2;
    },
    ...
    ]);

runTasksWithProgress немного сложно. В основном вы вызываете первую задачу, обновляете состояние, а затем настраиваете обратный вызов для запуска последующих задач.

Этот подход может облегчить некоторые боли.

0 голосов
/ 07 апреля 2010

Это все равно что спрашивать, возможно ли прервать процедуру, не прерывая процедуру. Ответ - нет. Вы должны использовать setTimeout () или setInterval (), чтобы передать управление движку рендеринга браузера.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...