同步读取数据库嵌套调用问题
Redis在Nodejs下keys, get都是异步的, 遇到一个问题, 需要 通过 keys 获取所有的key, 然后遍历通过get拿到key的值, 但是get是异步的, 刚开始上手做Node开发,这下给难住了,寻求帮助,看一下的代码有什么问题
var Thenjs = require('thenjs');
var redis = require("redis");
var client = redis.createClient(6379,'127.0.0.1');
client.on('error',function(error){
console.log(error);
});
var serviceUser = [];
function task(arg, callback) {
Thenjs.nextTick(function () {
callback(null, arg);
});
}
Thenjs(function (cont) {
client.keys('PHPREDIS_SESSION:*', function (err, keys) {
task(keys, cont);
});
})
.then(function (cont, keys) {
//console.log(keys);
Thenjs.eachSeries(keys, function (cont2, value) {
client.get(value, function(err, reply){
task(reply, cont2);
});
})
.then(function (cont2, result) {
var sessionStr = result.toString();
var reg = /account_name\|s:\d+:"([a-zA-Z0-9-_]+?)"/;
var match = reg.exec(sessionStr);
if(match) {
serviceUser.push(match[1]);
}
console.log(match[1]);
}).fin(cont);
})
.then(function(cont){
console.log('1');
})
.fin(function (cont, error, result) {
console.log('2');
cont();
});
发现fin没有执行, 需要将里面嵌套的结果在外层的fin中获取, 或者是外层的fin能够执行, 嵌套的each中,只循环了一次, 求教了
目前个人理解Thenjs.series符合内部嵌套的使用场景,但是Thenjs.series中的参数是不确定数量的,怎么操作啊
Thenjs.series([
function (cont) { task(88, cont); },
function (cont) { cont(null, 99); }
])
.then(function (cont, result) {
console.log(result);
});
2015-5-14 13:34:49 自己探索,改用bluebird解决
var redis = require("redis");
var Promise = require("bluebird");
var client = redis.createClient(6379,'127.0.0.1');
client.on('error',function(error){
console.log(error);
});
var serviceUser = [];
var getServiceName = function(str) {
var sessionStr = str.toString();
var reg = /account_name\|s:\d+:"([a-zA-Z0-9-_]+?)"/;
var match = reg.exec(sessionStr);
if(match) {
return match[1];
} else {
return false;
}
};
Promise.promisifyAll(redis);
client.keysAsync('PHPREDIS_SESSION:*').then(function(keys){
return keys;
}).each(function(key){
return client.getAsync(key).then(function(val){
var name = getServiceName(val);
if( name !== false) {
serviceUser.push(name);
}
console.log(name);
});
}).then(function(){
console.log(serviceUser);
});
注意each中的那个return这是关键,Promise.promisifyAll很强大,可以为模块所有的异步方法生成一个Promise版本方法, 例如 client.get对应 client.getAsync 可以看到代码简洁了许多
2015-5-18 11:31:08 ThenJs怎么实现总算是理解了,ThenJs的改进实现如下
var Thenjs = require('thenjs');
var _ = require('underscore');
function getServiceName(str) {
var sessionStr = str.toString();
var reg = /account_name\|s:\d+:"([a-zA-Z0-9-_]+?)"/;
var match = reg.exec(sessionStr);
if(match) {
return match[1];
} else {
return false;
}
};
var redis = require("redis");
var client = redis.createClient(6379,'127.0.0.1');
client.on('error',function(error){
console.log(error);
});
Thenjs(function (cont) {
client.keys('PHPREDIS_SESSION:*', cont);
})
.then(function (cont, keys) {
Thenjs.each(keys, function (cont2, key) {
client.get(key, cont2)
})
.then(function(cont2,val){
_.each(val, function(item){
var name = getServiceName(item);
console.log(name);
})
cont();
})
})
.then(function (cont) {
console.log('--- End ---');
});