我正在尝试使用异步库来处理异步函数,但我无法获得所需的功能。
基本思想是我使用对redis数据库的多次调用来构建JSON对象。我想在redis调用完成后才返回JSON对象,所以我尝试使用async.parallel
,但我似乎没有理解它。
使用空的JSON对象调用我的回调,然后看到函数中的控制台日志。
这是我的代码:
server.js:
getHostObject(redis,sess.hostName,function(data) {
console.log('calledback data: '+JSON.stringify(data));
});
getHostObject.js
var async = require('async');
var getHostObject = function(redis, hostName, callback) {
var hostObject = {
hostName: hostName,
pushers: [],
tracklist: []
};
var getSongObject = function(err,song) {
console.log('song got!');
hostObject.tracklist.push(song);
};
var getSongs = function() {
redis.lrange(hostName+":songs",0,-1, function(err,data) {
if (err) {console.log('Error reading songs! '+hostName+'\n'+err);}
for(var i=0;i<data.length;i++) {
redis.hgetall(hostName+":song:"+data[i], getSongObject);
}
});
};
var getPusherObject = function(err,pusher) {
console.log('pusher got!');
hostObject.pushers.push(pusher);
};
var getPushers = function() {
redis.smembers(hostName+":pushers", function(err, data) {
if (err) {console.log('Error reading pushers! '+hostName+'\n'+err);}
for(var i=0;i<data.length;i++) {
redis.hgetall(hostName+":pusher:"+data[i], getPusherObject);
}
});
};
async.parallel([
function() {
getPushers();
},
function() {
getSongs();
}
],callback(hostObject));
};
module.exports = getHostObject;
控制台输出:
calledback data: {"hostName":"47B71","pushers":[],"tracklist":[]}
pusher got!
song got!
答案 0 :(得分:1)
首先,在getHostObject
函数内,在async.parallel
调用中,您正在传递callback(hostObject)
。这将在异步代码执行之前进行评估,这就是hostObject
为空的原因。
除此之外,async.parallel需要知道您的个人任务何时完成。就是这样,你应该按照error, result
惯例调用任务回调。请查看文档中的the example。
您需要更改getPushers
和getSongs
以使用这些回调,将结果传递给回调,最后在并行完成cb中撰写hostObject
。
我试图根据您的代码进行说明,您需要对其进行修改才能使其正常工作。
var getSongs = function(cb) {
redis.lrange(hostName+":songs",0,-1, function(err,data) {
if (err) {console.log('Error reading songs! '+hostName+'\n'+err);}
for(var i=0;i<data.length;i++) {
redis.hgetall(hostName+":song:"+data[i], getSongObject);
}
// tracklistData should be the tracklist array, you need to build it first.
cb(null, tracklistData);
});
};
var getPushers = function(cb) {
redis.smembers(hostName+":pushers", function(err, data) {
if (err) {console.log('Error reading pushers! '+hostName+'\n'+err);}
for(var i=0;i<data.length;i++) {
redis.hgetall(hostName+":pusher:"+data[i], getPusherObject);
}
// pushersData should be the pushers array, you need to build it first
cb(null, pushersData);
});
};
async.parallel(getSongs, getPushers, function(err, results){
if(err) // err handling
callback({
hostName: hostName,
pushers: results[1],
tracklist: results[0]
});
});
当我评论你需要首先构建数组时,我的意思是你可能想在构建数组时在每个函数中使用async.parallel
。
也许像是
var getPushers = function(cb) {
redis.smembers(hostName+":pushers", function(err, data) {
var getOperations = [];
if (err) {console.log('Error reading pushers! '+hostName+'\n'+err);}
for(var i=0;i<data.length;i++) {
getOperations.push((function(pusher){
return function(callback){
redis.hgetall(hostName+":pusher:"+pusher, callback);
}
})(data[i]));
}
async.parallel(getOperations, function(err, pushers){
cb(null, pushers);
});
});
};