How to do Threading in Javascript
So I have a large JSON object i'm returning from the server, then building a datatable from it and displaying it on the form. This usually takes a few seconds.. so I was thinking of a loading bar. I have the logic behind the loading bar, however the loop that builds the hmtl data is locking down the browser and I cannot call out to the element i need to update.
Here is my function to do this:
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开发者_JAVA技巧,
"sScrollX": "100%"
});
});
}
[Added my comment as an answer]
JavaScript is single threaded. You'll have to break your work up into pieces and call them in sequence using "setTimeout" to allow the GUI to update during processing (in between your calls) but even then the browser will still seem somewhat unresponsive.
You can try using WebWorker: https://developer.mozilla.org/en/DOM/Worker
Thus worker are executed in parallel of the main thread, you cannot exactly achieve multi-threading using workers: you cannot modify the UI from a worker.
You can maybe create your grid as a string in a worker and when the worker finish, append it where you want.
If you do all the building of the Database in a setTimeout, the rest of the page should be responsive.
You can construct the html elements in that function, and when it is ready, attach it to the DOM. You will also have to call functions or send events to update the display of the progress bar.
Edit after comment:
This will run in background and won't affect responsiveness of the page:
window.setTimeout(function() {buildDataTable(db_table, container_id)}, 0);
You already update your progressbar from your function, so this should do it.
However, you might want to decouple the code generating the datatable from the code updating the progressbar.
So it appears the only clean way to do this in my application is to process the json on the server and build the html there. Then return the html to the browser via $.post()
The progress bar will be lost. however I can use a infinite loading gif...
精彩评论