我做了一些node.js代码来检索redis数据库中的数据,但我真的不高兴,我想改进它...
基本上,我的redis数据库中有一个“人”记录。从“人”我得到一个“人:我”的列表(我是一个整数),并为每个“人:我”,我做了一个额外的查询,以检索关键“人:我”的哈希。
我就是这样做的:
db.smembers("people", function(err1, people){
var jsonObj;
var jsonArr = [];
if(!err1) {
var i = 0;
res.writeHead(200, {'content-type': 'application/json'});
// people will provide a list like [person:1, person:2, ..., person:n]
people.forEach(function(person){
// In redis I get the hash with key "person:i"
db.hgetall(person, function(err2,obj){
if(!err2){
// Add person into array
jsonArr.push({ "id" : person.substring(7), "lastname" : obj["lastname"], "firstname" : obj["firstname"]});
// I'm not happy with this part where I check if I reached the last item of people array....
i = i + 1;
if(i == people.length){
res.write(JSON.stringify(jsonArr));
res.end();
}
} else {
var jsonObj = { "error" : "database error", "message" : "Cannot get hash " + person};
res.write(JSON.stringify(jsonObj));
res.end();
}
});
});
} else {
jsonObj = { "error" : "database error", "message" : err1.message };
res.writeHead(200, {'content-type': 'application/json'});
res.write(JSON.stringify(jsonObj));
res.end();
}
});
最干净的(至少是更干净的)方法是什么?
答案 0 :(得分:4)
您正在寻找的是异步控制流系统。一个例子是Step或streamline.js。
另一种方法是抽象流程,为Person创建一个数据模型,用于获取单个人对象,以及People模型,这是一个人员集合,其中包含一个方法,用于根据您所在的结构获取多个人使用
编辑:我找到了节点兼容控制流/异步库的完整列表:https://github.com/joyent/node/wiki/modules#wiki-async-flow
编辑:在审核完您的代码后,我想到了另一种非常特殊的替代方法,但没有直接解决问题的控制流性质。
通过更改架构以仅存储people
密钥中人员的ID,您可以使用redis的SORT
命令打开自己,这将使整个集合可以在单个命令中获取。要在redis中执行此操作:
> SADD people 1 2 3 4
> HMSET person:1 firstname John lastname Smith
> HMSET person:2 firstname Jane lastname Smith
> HMSET person:3 firstname John lastname Doe
> HMSET person:4 firstname Jane lastname Doe
> SORT people GET # GET person:*->firstname GET person:*->lastname
1) "1"
2) "Jane"
3) "Doe"
4) "2"
5) "Jane"
6) "Smith"
7) "3"
8) "John"
9) "Doe"
10) "4"
11) "Jane"
12) "Doe"
这可以在people
键中节省内存,并通过SORT
命令的by
和limit
选项启用分页/排序。