web-dev-qa-db-ja.com

Javascriptでスレッド化を行う方法

したがって、サーバーから返される大きな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%"
        });
    });
}
14
rlemon

[回答として私のコメントを追加]

JavaScriptはシングルスレッドです。作業を細かく分割し、「setTimeout」を使用して順番に呼び出す必要があります。これにより、処理中(呼び出しの合間に)にGUIを更新できますが、それでもブラウザーは多少応答しないように見えます。

20
maerics

WebWorkerを使用してみることができます: https://developer.mozilla.org/en/DOM/Worker
したがって、ワーカーはメインスレッドと並行して実行されるため、ワーカーを使用してマルチスレッドを正確に実現することはできません。ワーカーからUIを変更することはできません。
グリッドをワーカー内の文字列として作成し、ワーカーが終了したら、必要な場所に追加することができます。

3
F-A

SetTimeoutでデータベースのすべての構築を行う場合、ページの残りの部分はレスポンシブである必要があります。

その関数でhtml要素を作成し、準備ができたらDOMにアタッチできます。また、プログレスバーの表示を更新するには、関数を呼び出すか、イベントを送信する必要があります。

コメント後に編集:

これはバックグラウンドで実行され、ページの応答性には影響しません。

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

関数からプログレスバーを既に更新しているので、これで完了します。

ただし、データテーブルを生成するコードをプログレスバーを更新するコードから切り離したい場合があります。

2
Martin

したがって、私のアプリケーションでこれを行う唯一のクリーンな方法は、サーバーでjsonを処理し、そこでhtmlをビルドすることです。 Then$.post()を介してHTMLをブラウザに返します

プログレスバーは失われます。ただし、無限の読み込みgifを使用できます...

1
rlemon