如何在Javascript中进行线程化
所以我有一个大的JSON对象,我从服务器返回,然后从它构建一个数据表并在表单上显示它。 这通常需要几秒钟……所以我想到了一个加载栏。 我有加载栏背后的逻辑,但是构建hmtl数据的循环是锁定浏览器而我无法调用我需要更新的元素。
这是我的function:
function buildDataTable(db_table, container_id) { var $pb = $(""); $(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 += "" + key.replace(" ", " ") + " "; } for (i in jsonObject) { contents += ""; for (j in jsonObject[i]) { contents += "" + jsonObject[i][j] + " "; } contents += " "; 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 = "" + headers + " " + contents + "
"; $(container_id).html(html); $(container_id).children("table:first").dataTable({ "bJQueryUI": true, "sScrollX": "100%" }); }); }
[添加我的评论作为答案]
JavaScript是单线程的。 你必须将你的工作分成几部分,然后使用“setTimeout”按顺序调用它们以允许GUI在处理期间(在你的调用之间)更新,但即使这样,浏览器仍然会显得有点无响应。
您可以尝试使用WebWorker: https : //developer.mozilla.org/en/DOM/Worker
因此,worker与主线程并行执行,您无法使用worker完全实现multithreading:您无法从工作者修改UI。
您可以在工作人员中将网格创建为字符串,当工作人员完成时,将其附加到您想要的位置。
如果您在setTimeout中完成数据库的所有构建,则页面的其余部分应该是响应式的。
您可以在该函数中构造html元素,并在准备好后将其附加到DOM。 您还必须调用函数或发送事件来更新进度条的显示。
评论后编辑:
这将在后台运行,不会影响页面的响应性:
window.setTimeout(function() {buildDataTable(db_table, container_id)}, 0);
您已经从函数中更新了进度条,因此应该这样做。
但是,您可能希望将生成数据表的代码与更新进度条的代码分离。
因此,在我的应用程序中执行此操作的唯一干净方法似乎是在服务器上处理json并在那里构建html。 然后通过$.post()
将html返回给浏览器
进度条将丢失。 但是我可以使用无限加载gif …