我在Node中处理一个涉及多个async.map
调用的场景,其中一个调用嵌套在_.map
函数中,因为我需要访问嵌套数组。我正在努力将这些调用的结果正确地组合成一个我最后返回的数组。
有关该方案的更多细节:
我从userId
开始,查询我的游戏数据库,找到与此userId相关联的所有games
。我为每场比赛拉gameId
和description
。
然后我查询每个游戏的gameId
以查找与每个游戏相关联的所有userId
。我从这些结果中过滤了原始的userId
。
接下来,我为每个userId
查询我的用户数据库,以获取用户email
和name
等详细信息。 (注意:这是_.map
发挥作用的地方,因为userId
嵌套在一个数组数组中;每个内部数组代表一个游戏。)
最后一步,也是我挣扎的地方,就是如何将这些结果结合起来并归还它们。我最后想要的数组如下所示。一系列游戏对象。每个游戏对象都有gameId
,description
和users
属性。 users
是与该游戏相关联的一系列用户,并且具有id
,email
和name
属性。
[
{
gameId: 'dfh48643hdgf',
description: 'lorem ipsum...',
users: [
{
id: 1,
email: 'test@example.com',
name: 'John Doe'
},
{
id: 7,
email: 'sample@example.com',
name: 'Jane Smith'
}, ...
]
}, ...
]
下面是我目前的代码(注意:此代码块实际上是更大async.series
调用的一部分):
sharedGames: function(next) {
db.games.index({userId: userId},
function(err, gamesData) {
if (err) {
logger.warn('Error retrieving games for 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, []);
}
}
);
}
答案 0 :(得分:0)
所以你绝对可以用async.auto
完成你所描述的内容。从他们的文档中查看:
async.auto({
get_data: function(callback){
console.log('in get_data');
// async code to get some data
callback(null, 'data', 'converted to array');
},
make_folder: function(callback){
console.log('in make_folder');
// async code to create a directory to store a file in
// this is run at the same time as getting the data
callback(null, 'folder');
},
write_file: ['get_data', 'make_folder', function(callback, results){
console.log('in write_file', JSON.stringify(results));
// once there is some data and the directory exists,
// write the data to a file in the directory
callback(null, 'filename');
}],
email_link: ['write_file', function(callback, results){
console.log('in email_link', JSON.stringify(results));
// once the file is written let's email a link to it...
// results.write_file contains the filename returned by write_file.
callback(null, {'file':results.write_file, 'email':'user@example.com'});
}]
}, function(err, results) {
console.log('err = ', err);
console.log('results = ', results);
});
因此,如果您遵循相同的方法,您可以通过在每次调用时注入更多信息来获取游戏对象数组。您也可以使用async.waterfall
。希望它有所帮助