Как сделать 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(" ", " ") + "</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%"
});
});
}
Ответы
Ответ 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...