4

ここに私が持っているものがあります:

  1. 長い (2 ~ 10 秒) 計算 (db + 外部 API 呼び出し) を実行する Node.js 関数。async.auto()呼び出しの依存関係を整理するために使用します
  2. HTML ビュー ページの見栄えの良いプログレス バー
  3. クエリを呼び出す getJSON 関数 (以下のコードを参照)

現在、タイマーの進行状況バーを更新しています。でももっと正確にしてほしい。私はすでにサーバー側関数を 5 つのマイルストーン (つまり、すべての外部呼び出しが正常に終了した後) に分割しており、その進捗情報をクライアントに送信したいと考えています。ただし、res.send(progress)応答を完了すると、それ以上何も送信できなくなります。

ここでは明らかに別のパターンが必要であり、いくつかのアイデアがありました。

  1. 2 つの ajax 呼び出し。1 つは進行状況をポーリングし、2 番目は結果を取得します。
  2. サーバー側の機能がなくなるまで、5 回呼び出される 1 つの呼び出し
  3. まったく異なるもの (おそらくロングポーリング、Websockets など)

質問:

推奨されるパターンと、サーバー側とクライアント側の両方でそれを実装する方法を知りたいです。サンプル コード、またはサンプルへのリンクは大歓迎です。

そして、いつもありがとうございます!

ここに含まれているのは、これまでのコードです (明らかな機能の省略があります)。この質問に必ずしも答える必要はありませんが、状況を説明するためにここで答えます。

クライアント

var searchFunction = function() {
        var user = $("#searchTerm").val();
        $.getJSON("/search/" + user, function(data) {
            console.log(data);
            ko.applyBindings(new MyViewModel(data));
        });
        $("#content").hide();
        progressBar(5);
        $("#progress_bar").show();
        setTimeout(function() {
            progressBar(25);
        }, 1000);
        setTimeout(function() {
            progressBar(50);
        }, 2000);
        setTimeout(function() {
            progressBar(75);
        }, 3000);
        setTimeout(function() {
            $("#progress_bar").hide();
            $("#content").show();   
        }, 4000);
    };

サーバ

var searchFunction = function(req, res) {   
    async.auto({
        f1: function(callback) {
            //things happen
            callback(err, res);
        },
        f2: function(callback) {
            //things happen
            callback(err, res);
        },
        f3: ['f2', function(callback, result) {
            //many things happen
            callback(err, res);
        }, 
        function(err) {
            //decisions are made
            callback(null, watchers);
        }]  
    }, function(err, result) {  
            //more exciting stuff happens       
            res.send(finalResults);
        }
    );
};
4

2 に答える 2

2

私が最初に考えたのは、socket.io などを使用して、サーバーが各マイルストーンでイベントを発行することです。クライアント側バージョンの searchFunction() は、単純に AJAX 呼び出しを行ってから戻り、ソケット ハンドラーがプログレス バーの更新を処理します。

于 2012-10-06T03:13:57.420 に答える
2

イベント ストリームを使用して、完了率の値をクライアントにプッシュすることができます。ただし、最新のブラウザでのみ機能します。IE9+ だと思います。イベント ストリームの例を次に示します: https://github.com/chovy/nodejs-stream

html

<div id="progress"><span class="bar"></span></div>

CSS

#progress { width: 200px; background: #eee; border: 1px solid #ccc; height: 20px; }
#progress .bar { display: inline-block; background: #ddd; width: 0; }

クライアント側 (jQuery) - /progress イベント ストリームをリッスンする

var source = new EventSource('progress');
source.addEventListener('progress', function(e) {
  var percentage = JSON.parse(e.data),
  //update progress bar in client
  $("#progress .bar").css({ width: percentage });
}, false);

サーバー側 - 新しい進捗率でイベントをプッシュする

res.writeHead(200, {'Content-Type': 'text/event-stream'});
res.write("event: progress\n");
//push the percentage to the client (ie: "10%")
res.write("data: "+"10%".toString()+"\n\n");

UI でプログレス バーを定義するのはあなた次第です --- パーセンテージ ベースの幅を持つ CSS ルールを持つ子を持つ固定幅の div を使用します。それが更新されます。

于 2012-10-06T05:36:54.843 に答える