我需要一个由数据库查询备份的redis查询的异步包装器。如果redis查询失败,我想进行数据库查询。如果数据库查询成功,我希望在返回之前将返回的数据添加到redis中。我需要函数(希望是对象上的几个这样的方法之一(来返回promise,因为它将从node.js中调用。我正在使用bluebird-promises库,并使用它来promiseredis。我使用的是mongo陀螺仪的数据库,这也是基于蓝鸟。这两者都是独立工作的。
感谢任何帮助,甚至伪代码,特别是错误处理
function get_something(key){
redis.get(key).done(function (res){
if (null !== res){
return res; // how do I return a promise here?
}
})
.done(function (res){
db.find({'_id:key'}).done(function (res){
if (null !== res){
redis.set(key,result) // set db value in redis
.then(function(){
return res; //how do I return a promise here?
})
.catch()...?
return res; // how do I return a promise here?
}
})
.catch...?
};
更新:下面的函数可以工作,final然后显示来自redis或mongo的数据。然而,到目前为止,我还没有成功地将其转换为类上的一个方法,该方法返回将返回给node.js处理程序的promise。NB-我需要添加"绑定",以便捕获数据的来源
var oid = '+++++ test oid ++++++'
var odata = {
'story': 'once upon a time'
}
var rkey = 'objects:'+ oid
redis.getAsync(rkey).bind(this).then(function(res){
if(res === null){
this.from = 'db' // we got from db
return db.findOne('objects',{'_id':oid})
}
data = JSON.parse(res)
this.from = 'redis' // we got from redis
return data
})
.then(function(res){
if(res !== null && this.from == 'db'){
data = JSON.stringify(res)
redis.setAsync(rkey,data)
}
return res
})
.then(function(res){ // at this point, res is not a promise
console.log('result from ' + this.from)
console.log(res)
});
.done
终止承诺链。一般来说,蓝鸟足够聪明,能够独自处理未经处理的拒绝。
你要找的是.then
:
redis.get(key).then(function(res){ res is redis .get response
if(res === null) throw new Error("Invalid Result for key");
return db.find({"_id":key); // had SyntaxError here, so guessing you meant this
}).then(function(res){ // res is redis .find response
return redis.set(key,result);
}).catch(function(k){ k.message === "Invalid Result for key",function(err){
// handle no key found
});
Ideotype,根据我对您最初的问题和更新的理解,我相信您可以实现您的目标,而不需要跟踪哪个来源产生了所需数据的标志。
像这样的东西应该起作用:
function get_something(oid) {
var rkey = 'objects:' + oid;
return redis.getAsync(rkey).then(function(res_r) {
if (res_r === null) {
return Promise.cast(db.findOne('objects', {'_id': oid})).then(function(res_db) {
redis.setAsync(rkey, res_db).fail(function() {
console.error('Failed to save ' + rkey + ' to redis');
});
return res_db;
});
}
return res_r;
}).then(function (res) {//res here is the result delivered by either redis.getAsync() or db.find()
if (res === null) {
throw ('No value for: ' + rkey);
}
return res;
});
}
注:
- 您可能需要使用
oid
和rkey
修复线路。我在这里的理解是有限的 - 这里的模式很不寻常,因为mongo陀螺仪查询是可选的,随后的redis更新是关于整个功能成功的学术性更新
Promise.cast()
包装器可能是不必要的,这取决于db.findOne()
返回的内容- 毫无疑问,这将受益于对蓝鸟有更好了解的人的一次复习