如何在Javascript中进行线程化

时间:2011-08-09 15:02:36

标签: javascript jquery multithreading jquery-ui progress-bar

所以我有一个大的JSON对象,我从服务器返回,然后从它构建一个数据表并在表单上显示它。这通常需要几秒钟......所以我想到了一个加载栏。 我有加载栏背后的逻辑,但是构建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%"
        });
    });
}

4 个答案:

答案 0 :(得分:20)

[添加了我的评论作为答案]

JavaScript是单线程的。你必须将你的工作分成几部分并使用“setTimeout”按顺序调用它们以允许GUI在处理期间(在你的调用之间)更新,但即使这样,浏览器仍然会显得有点无响应。

答案 1 :(得分:3)

您可以尝试使用WebWorker:https://developer.mozilla.org/en/DOM/Worker
因此,worker与主线程并行执行,您无法使用worker完全实现多线程:您无法修改工作者的UI。
您可以在工作人员中将网格创建为字符串,当工人完成时,将其附加到您想要的位置。

答案 2 :(得分:2)

如果您在setTimeout中完成数据库的所有构建,则页面的其余部分应该是响应式的。

您可以在该函数中构造html元素,并在准备好后将其附加到DOM。您还必须调用函数或发送事件来更新进度条的显示。

评论后修改:

这将在后台运行,不会影响页面的响应性:

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

您已经从功能中更新了进度条,因此应该这样做。

但是,您可能希望将生成数据表的代码与更新进度条的代码分离。

答案 3 :(得分:1)

所以看来在我的应用程序中唯一干净的方法是在服务器上处理json并在那里构建html。 然后通过$.post()

将html返回到浏览器

进度条将丢失。但是我可以使用无限加载的GIF ......