如何在Javascript中进行线程化

时间:2022-01-23 21:01:39

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(" ", "&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 个解决方案

#1


20  

[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在处理期间(在你的调用之间)更新,但即使这样,浏览器仍然会显得有点无响应。

#2


3  

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完全实现多线程:您无法从工作者修改UI 。您可以在工作人员中将网格创建为字符串,当工作人员完成时,将其附加到您想要的位置。

#3


2  

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.

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

#4


0  

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()

因此,在我的应用程序中执行此操作的唯一干净方法似乎是在服务器上处理json并在那里构建html。然后通过$ .post()将html返回给浏览器

The progress bar will be lost. however I can use a infinite loading gif...

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

#1


20  

[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在处理期间(在你的调用之间)更新,但即使这样,浏览器仍然会显得有点无响应。

#2


3  

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完全实现多线程:您无法从工作者修改UI 。您可以在工作人员中将网格创建为字符串,当工作人员完成时,将其附加到您想要的位置。

#3


2  

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.

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

#4


0  

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()

因此,在我的应用程序中执行此操作的唯一干净方法似乎是在服务器上处理json并在那里构建html。然后通过$ .post()将html返回给浏览器

The progress bar will be lost. however I can use a infinite loading gif...

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

相关文章