javascript - How to handle results of multiple async callbacks in Node -
i'm working on scenario in node involves multiple async.map
calls, 1 of nested in _.map
function need access nested arrays. i'm struggling combine results of these calls array return in end.
more specifics on scenario:
i start userid
, query games db find games
userid associated with. pull gameid
, description
each game.
i query gameid
of each of these games find userid
s associated each game. filter original userid
out of these results.
next query users db each of these userid
s in order details such user email
, name
. (note: _.map
comes play userid
s nested in array of arrays; each inner array representing game).
the last step, , i'm struggling, how combine these results , return them. final desired array looks below. array of game objects. each game object has gameid
, description
, , users
property. users
array of users associated game , has id
, email
, , name
properties.
[ { gameid: 'dfh48643hdgf', description: 'lorem ipsum...', users: [ { id: 1, email: 'test@example.com', name: 'john doe' }, { id: 7, email: 'sample@example.com', name: 'jane smith' }, ... ] }, ... ]
below code have (note: code block part of larger async.series
call):
sharedgames: function(next) { db.games.index({userid: userid}, function(err, gamesdata) { if (err) { logger.warn('error retrieving games userid %d', userid, err); next(err, null); } else { gamesdata = _.map(gamesdata, function(game) { return { gameid: game.id, description: game.description, users: [] }; }); async.map(gamesdata, function(item, callback) { db.gamedetails.getgameusers({gameid: item.gameid}, function(err, users) { if (err) { callback(err, null); } else { callback(null, _.without(users.userids, number(userid))); } } ); }, function(err, results) { if (err) { next(null, null); } else { var flattenedresults = _.chain(results) .flatten() .uniq() .value(); async.map(flattenedresults, function(user, callback) { db.users.getbyid(user, function(err, userdetails) { if (err) { callback(err, null); } else { callback(null, _.pick(userdetails, 'id', 'email', 'name')); } }); }, function(err, users) { if (err) { next(null, null); } else { _.each(results, function(result, index) { _.each(result, function(user) { var customerdetails = _.find(customers, function(u) { return u.id === user; }); gamesdata[index].users.push(userdetails); }); }); console.log(gamesdata); next(null, gamesdata); } }); } } ); next(null, []); } } ); }
so can accomplish you're describing async.auto
. check docs:
async.auto({ get_data: function(callback){ console.log('in get_data'); // async code data callback(null, 'data', 'converted array'); }, make_folder: function(callback){ console.log('in make_folder'); // async code create directory store file in // run @ same time getting data callback(null, 'folder'); }, write_file: ['get_data', 'make_folder', function(callback, results){ console.log('in write_file', json.stringify(results)); // once there data , directory exists, // write data file in directory callback(null, 'filename'); }], email_link: ['write_file', function(callback, results){ console.log('in email_link', json.stringify(results)); // once file written let's email link it... // results.write_file contains filename returned write_file. callback(null, {'file':results.write_file, 'email':'user@example.com'}); }] }, function(err, results) { console.log('err = ', err); console.log('results = ', results); });
so if follow same approach, can array of game objects injecting more info every call. can use async.waterfall
. hope helps
Comments
Post a Comment