3

以下はroutes/index.jsからの私のコードのスナップショットです

exports.index = function(req, res){
    var results=new Array();
    for(var i=0; i<1000;i++){
        //do database query or time intensive task here based on i 
        // add each result to the results array
    }
    res.render('index', { title: 'Home !' , results:results });
};

このコードを実行すると、JavaScriptの非同期性により、ループが完全に処理される前に最後の行が実行されます。したがって、私のWebページには結果がありません。クエリが完了するとページが読み込まれるようにこれを構成するにはどうすればよいですか?


更新しました

ループ内には、次のようなデータベースコード(Redis)があります-

client.hgetall("game:" +i, function(err, reply) {

           results.push(reply.name);
        });
4

2 に答える 2

6

非同期ライブラリを使用します:

exports.index = function(req, res){
    var results=new Array();
    async.forEach(someArray, function(item, callback){
        // call this callback when any asynchronous processing is done and
        // this iteration of the loop can be considered complete
        callback();
    // function to run after loop has completed
    }, function(err) {
        if ( !err) res.render('index', { title: 'Home !' , results:results });
    });
};

ループ内のタスクの 1 つが非同期の場合、非同期タスクに を呼び出すコールバックを渡す必要がありますcallback()。で使用する配列がない場合は、配列にforEach1 ~ 1000 の整数を入力します。

編集:最新のコードを考えると、の直後に置くだけasync callback()ですresponses.push(reply.name)

于 2012-12-17T02:22:08.697 に答える
3
exports.index = function(req, res) {
  var events = require("events");
  var e = new events.EventEmitter();
  e.expected = 1000;
  e.finished = 0;
  e.results = [];

  e.on("finishedQuery", (function(err, r) {
    this.finished += 1;
    this.results.push(r && r.name);
    if (this.finished === this.expected) {
       res.render('index', { title: 'Home !' , results:this.results });
    };
  }).bind(e));

  for (var i = 0; i < e.expected; i++) {
    client.hgetall("game:" + i, function(err, reply) {
      e.emit("finishedQuery", err, reply);
    });
  };
};

もちろん、上記のコードは [1 つ以上の] エラーを処理しません。(1) 最初のエラーが発生した場合、または (2) エラーが発生しなかった場合にのみ応答するロジックを追加する必要があります。

于 2012-12-17T19:06:34.297 に答える