web-dev-qa-db-ja.com

各ループで同じ値を返すNode.js for()ループ

Nodejsを探索するのに役立つこの非常に単純なアプリケーションを作成しています。データベース内のトップ10メッセージに基づいてHTMLコードを生成する特定のハンドラーがあります。メッセージをループし、HTMLを生成する関数を呼び出して、HTML文字列に結果を追加する際に問題があるスニペット。

function CreateMessageboard(BoardMessages){
  var htmlMessageboardString = "";

  [... Console debug code ...]

  for(var i = 0; i < BoardMessages.length;i++){
        (function(){
            var j = i;
            console.log("Loading message %d".green, j);
            htmlMessageboardString += MessageToHTMLString(BoardMessages[j]);
          })();
  }
}

私の問題は、私が読んだものからのクロージャーに関連するループを処理するJavascriptの方法またはこれが上記で使用しようとしたものであるか、nodejsが私の関数を処理する非同期方法のいずれかによると思います。現在、データベースから10個の結果が返されていますが、最後のメッセージはループごとに処理されます。

また、var j = iを実行する代わりに、値iを関数パラメーターとして受け取り、クロージャーに渡すことを試みましたが、とにかく同じ結果を返しました。

私は自分の問題を解決するための重要な知識が不足していると感じていますが、この問題に光を当てることはできますか?

編集:コードに関する他の情報を提供することを歓迎します.gitリポジトリ全体を投稿しますが、おそらくこの問題をデバッグするためにプロジェクト全体を泳ぎたくないので、関数全体をより多くのコンテキストを提供するコメント。

13
Tristan Dubé
  for(var i = 0; i < BoardMessages.length;i++){
        (function(j){
            console.log("Loading message %d".green, j);
            htmlMessageboardString += MessageToHTMLString(BoardMessages[j]);
        })(i);
  }

それはうまくいくはずです。ただし、ループ内で関数を作成しないでください。したがって、

  for(var i = 0; i < BoardMessages.length;i++){
        composeMessage(BoardMessages[i]);
  }

  function composeMessage(message){
      console.log("Loading message %d".green, message);
      htmlMessageboardString += MessageToHTMLString(message);
  }
25
Joe

より機能的なスタイルでこれを行うことをお勧めします:P

function CreateMessageboard(BoardMessages) {
  var htmlMessageboardString = BoardMessages
   .map(function(BoardMessage) {
     return MessageToHTMLString(BoardMessage);
   })
   .join('');
}

これを試して

3
ming_codes