调用节点异步回调以完成操作
Node async callback being called for operations complete
我正在尝试使用异步库来处理异步函数,但无法获得我需要的功能。
基本思路是,我正在使用对 redis 数据库的多次调用构建一个 JSON 对象。在 redis 调用完成后,我只想 return 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!
首先,在 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);
});
});
};
我正在尝试使用异步库来处理异步函数,但无法获得我需要的功能。
基本思路是,我正在使用对 redis 数据库的多次调用构建一个 JSON 对象。在 redis 调用完成后,我只想 return 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!
首先,在 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);
});
});
};