2016-08-01 38 views
0

Was ist das Problem mit diesem NodeJS Code?nodejs async Kontrollfluss mit Schleife

Ich habe das folgende NodeJS-Snipt.

Profile.findOne(profileId, cb) //is sync function 


function getProfiles(users, cb) { 
    var results = []; 
    var n = users.length; 
    users.forEach(function(user, i) { 
    Profile.findOne(user.profileId, function(err, prf) { 
     if (err) { 
     return cb(err, null); 
     } 
     console.log(prf); 
     console.log(user.profileId); 
     results.push(prf); 
     if (i + 1 == n) { 
     console.log('looping done'); 
     return cb(null, results); 
     } 
    }); 
    }); 
} 

// some where 
var userslist = [{ 
    name: 'ab', 
    profileId: 'daf242' 
}, { 
    name: 'cd', 
    profileId: 'hg535h' 
}, { 
    name: 'ef', 
    profileId: 'cvxv445' 
}]; 
getProfiles(userslist, function(err, data) { 
    if (err) { 
    //do this 
    } else { 
    //do that 
    } 
}); 

Das Problem ist, die Ergebnisse sind Array von nurProfilen für das erste das Profil. wie

[ 
     {username:'ab',avatarUrl:'abcd.png'} 
     {username:'ab',avatarUrl:'abcd.png'}, 
     {username:'ab',avatarUrl:'abcd.png'} 
    ] 

aber ich erwarte Array von differnet Profile.

was fehlt mir?

+0

Try this: https://jsfiddle.net/rayon_1990/Ldd0mcrj/ – Rayon

Antwort

1

Sie mischen synchronen und asynchronen Code hier. Ihre forEach-Schleife wird synchron ausgeführt, aber die Methode Profile.findOne ist asynchron. Es ruft dann den Rückruf auf, der an die Anfangsfunktion übergeben wurde. Sie sollten mit async for an asynchronous for loop suchen.

Es gibt jedoch viele Dinge in Ihrer Frage, die darauf hinweisen, dass Sie die asynchrone Natur von Node.js noch nicht vollständig erfasst haben. Versuchen Sie, das Thema zu lesen, z. B. callback hell.

+0

Können Sie das näher erläutern _ "den Rückruf in die Ausgangs Funktion übergeben ruft" _? – Rayon

+0

@MrWillihog könnten Sie einen Weg vorschlagen, um das Problem zu beheben, werde ich die Links lesen und das Thema aufhellen. aber jetzt brauche ich qucik suggetion/fix. – Zstudent

+0

@Rayon - die Funktion 'getProfiles' wird als Callback übergeben (' cb'). Dies wird innerhalb der 'Profile.findOne' Methode aufgerufen. In der Tat wird das erste gefundene Profil sein Ergebnis an den Callback der 'getProfiles'-Funktion übergeben. – MrWillihog

0

Verwenden async oder verspricht

var async = require('async'); 
... 
async.map(users, Profile.findOne, function(err, results) { 
    if (err) 
     return ...// process errors; 

    userlist = results; 
})