2012-04-19 22 views
10

Tworzę tę naprawdę prostą aplikację, która pomoże mi eksplorować nodejs i mam konkretny program, który generuje kod HTML na podstawie 10 wiadomości w mojej bazie danych. Fragment mam problem z pętlami przez wiadomości i wywołuję funkcję generującą HTML i dołącza wynik do mojego łańcucha html.Node.js dla() pętli zwracającej te same wartości w każdej pętli

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]); 
      })(); 
    } 
} 

Myślę, że mój problem jest ze względu na sposób Either JavaScript w obchodzenia pętle, związane z zamknięciami z tego co czytałem i to, co próbowałem przy użyciu powyżej lub sposób asynchroniczny nodejs obsługuje moją funkcję. Obecnie 10 wyników jest dobrze zwracanych z bazy danych, ale ostatnia wiadomość jest przetwarzana w każdej pętli.

Próbowałem również, zamiast robić var ​​j = i, przyjąć wartość i jako parametr funkcji i przekazać go w zamknięciu i mimo to zwróciło takie same wyniki.

Mam przeczucie, że brakuje mi krytycznej wiedzy, aby rozwiązać mój problem, czy mogę się o tym przekonać?

Edycja: Zapraszam do podania innych informacji na temat kodu, opublikuję całe repozytorium git, ale ludzie prawdopodobnie nie chcą przepłynąć przez cały projekt, aby pomóc mi w debugowaniu tego problemu, więc napisałem cała funkcja w komentarzach, aby zapewnić więcej kontekstu.

+3

Powinno działać nawet bez funkcji, ponieważ nie masz żadnych innych zamknięć, które mogłyby przypadkowo uchwycić 'i'. Czy to twój dokładny kod? –

+0

Jak mówi @MatthewFlaschen, kod wygląda dobrze. Możesz jednak wypróbować 'function (i) {......}) (i);' tak, że nie ma wątpliwości, że 'i' jest przechwytywane. –

+2

Podejrzewam, że musisz uwzględnić więcej kontekstu; błąd nie pojawia się tutaj – Kato

Odpowiedz

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

To powinno działać; jednak nigdy nie powinieneś tworzyć funkcji w pętli. W związku z tym,

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

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

Nie ma nic złego w tworzeniu anonimowej funkcji w pętli, o ile zakres jest poprawnie wykonany. –

+1

@MatthewFlaschen, Lub podjąć złożoność prawidłowego wykreślenia z równania. – Joe

3

Proponuję robić to w stylu bardziej funkcjonalny: P

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

Spróbuj

Powiązane problemy