Подтвердить что ты не робот

Как сделать Threading в Javascript

Итак, у меня есть большой объект JSON, который я возвращаюсь с сервера, а затем создаю из него datatable и отображаю его в форме. Обычно это занимает несколько секунд. Поэтому я думал о загрузочном баре. У меня есть логика за панель загрузки, однако цикл, который строит данные hmtl, блокирует браузер, и я не могу вызвать элемент, который мне нужно обновить.

Вот моя функция:

function buildDataTable(db_table, container_id) {
    var $pb = $("<div id=\"progress-bar\"></div>");
    $(container_id).html($pb);
    $pb.progressbar({
        value: 0
    });
    $.post("post location", {
        view: "all"
    }, function (data) {
        var headers = "";
        var contents = "";
        var jsonObject = $.parseJSON(data);
        var tik = Math.round(jsonObject.length / 100);
    for (key in jsonObject[0]) {
            headers += "<th>" + key.replace(" ", "&nbsp;") + "</th>";
        }
        for (i in jsonObject) {
            contents += "<tr>";
            for (j in jsonObject[i]) {
                contents += "<td class=\"border-right\">" + jsonObject[i][j] + "</td>";
            }
            contents += "</tr>";
            if(Math.round(i/tik) == i/tik) {
/* if I run the alert (between popups) i can see the progressbar update, otherwise I see no update, the progressbar appears empty then the $(container_id) element is updated with the table i've generated */
                alert(''); 
                $pb.progressbar("value",i/tik);
            }
        }
        var html = "<table cellpadding=\"5\" cellspacing=\"0\"><thead><tr>" + headers + "</tr></thead><tbody>" + contents + "</tbody></table>";

        $(container_id).html(html);
        $(container_id).children("table:first").dataTable({
            "bJQueryUI": true,
            "sScrollX": "100%"
        });
    });
}
4b9b3361

Ответ 1

[Добавлен комментарий в качестве ответа]

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

Ответ 2

Вы можете попробовать использовать WebWorker: https://developer.mozilla.org/en/DOM/Worker
Таким образом, рабочий выполняется параллельно основному потоку, вы не можете точно достичь многопоточности с использованием рабочих: вы не можете изменять пользовательский интерфейс от рабочего.
Возможно, вы можете создать свою сетку в виде строки в рабочем месте, а когда рабочий закончите, добавьте ее туда, где хотите.

Ответ 3

Если вы делаете все здание базы данных в setTimeout, остальная часть страницы должна реагировать.

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

Изменить после комментария:

Это будет работать в фоновом режиме и не повлияет на отзывчивость страницы:

window.setTimeout(function() {buildDataTable(db_table, container_id)}, 0);

Вы уже обновили свой индикатор прогресса от своей функции, поэтому это должно сделать это.

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

Ответ 4

Итак, единственный способ сделать это в моем приложении - обработать json на сервере и построить там html. Затем верните html в браузер через $.post()

Индикатор выполнения будет потерян. однако я могу использовать бесконечную загрузку gif...