如何在 Javascript 中进行线程处理
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6998330/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to do Threading in Javascript
提问by rlemon
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.
所以我有一个从服务器返回的大型 JSON 对象,然后从中构建一个数据表并将其显示在表单上。这通常需要几秒钟..所以我在想一个加载栏。我在加载栏后面有逻辑,但是构建 hmtl 数据的循环正在锁定浏览器,我无法调用我需要更新的元素。
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,
"sScrollX": "100%"
});
});
}
回答by maerics
[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.
JavaScript 是单线程的。您必须将您的工作分解成多个部分,并使用“setTimeout”按顺序调用它们,以允许 GUI 在处理期间(在您的调用之间)进行更新,但即使如此,浏览器似乎仍然有些无响应。
回答by F-A
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.
您可以尝试使用 WebWorker:https: //developer.mozilla.org/en/DOM/Worker
因此worker 与主线程并行执行,您无法使用worker 准确实现多线程:您无法从worker 修改UI .
您可以在工作人员中将网格创建为字符串,并在工作人员完成后将其附加到您想要的位置。
回答by Martin
If you do all the building of the Database in a setTimeout, the rest of the page should be responsive.
如果您在 setTimeout 中完成数据库的所有构建,则页面的其余部分应该是响应式的。
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.
您可以在该函数中构造 html 元素,并在准备就绪后将其附加到 DOM。您还必须调用函数或发送事件来更新进度条的显示。
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);
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.
但是,您可能希望将生成数据表的代码与更新进度条的代码分离。
回答by rlemon
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. Thenreturn the html to the browser via $.post()
因此,在我的应用程序中执行此操作的唯一干净方法似乎是在服务器上处理 json 并在那里构建 html。然后通过以下方式将html返回到浏览器$.post()
The progress bar will be lost. however I can use a infinite loading gif...
进度条将丢失。但是我可以使用无限加载gif ...