2016-08-01 7 views
0

В чем проблема с этим кодом NodeJS?nodejs async control flow with loop

У меня есть следующий 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 
    } 
}); 

Проблема представляет результаты массив толькопрофилей для первого ProfileID. как

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

, но я ожидал массив Differnet профилей.

Что мне не хватает?

+0

Попробуйте это: https://jsfiddle.net/rayon_1990/Ldd0mcrj/ – Rayon

ответ

1

Здесь вы смешиваете синхронный и асинхронный код. Ваш цикл forEach работает синхронно, но метод Profile.findOne является асинхронным. Затем он вызывает обратный вызов, переданный в начальную функцию. Вы должны посмотреть на использование async for an asynchronous for loop.

Однако в вашем вопросе есть много вещей, которые предполагают, что вы еще не полностью поняли асинхронный характер Node.js. Попробуйте прочитать эту тему, например, callback hell.

+0

Вы можете уточнить _ «вызывает функцию обратного вызова передается в исходную функцию» _? – Rayon

+0

@MrWillihog вы могли бы предложить способ решить проблему, я прочитаю ссылки и осветлю тему. но теперь я как бы нуждаюсь в qucik suggestetion/fix. – Zstudent

+0

@Rayon - функция getProfiles передается обратным вызовом ('cb'). Это вызвано внутри метода 'Profile.findOne'. Таким образом, первый профиль, который будет найден, передаст его результат обратному вызову функции getProfiles. – MrWillihog

0

Использование async или обещает

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

    userlist = results; 
})