假如我有一个查询用户数据的需求,逻辑是这样的:先从缓存查,如果缓存里没有,再从数据库查,我用promise实现如下:
exports.getUserData=function(){
return redis.getAsync().then(function(val){
if(val)
return db.findFromDB(sql).then(function(val){
return val;
});
else return val;
}).catch(function(error){
//....
});
}
我怎么感觉我这样的写法和多层callback没区别了,是我写法不对吗?
你这写法不能说不对,但是可读性有点尴尬。。。可以这样组织逻辑
Promise.resolve()
.then(function(){
return redis.getAsync();
})
.then(function(val){
if(val) return db.findFromDB(sql);
return val;
})
.then(function(val){
//TODO: sth
})
.catch(function(err){
//TODO: err
});
@lgyhitler 这样的话 上面的代码能封装成一个函数么? 我试了下 假如上面代码封装函数名为getUserData(),应该如何调用? 其实我要的就是上面的代码是一个函数,另外一个函数调用该函数,拿到该函数返回的值做输出!
你应该是没搞明白Promise得真正意图,整个流程都是异步的所以会出现层层callback,Promise相当于用一种封装的形式来代替callback,每个then都是异步的,但是每个then()返回的都是一个Promise对象,这样的话就允许实现类似链式调用的方式进行流程控制。你若是想将上面的封装成一个函数,那就调用它的方式还得是Promise。 比如上面的封装成 函数getUserData,那调用方式就是:
function Fn(){
Promise.resolve()
.then(function(){
return getUserData();
})
.then(function(userData){
//TODO: userData
})
}
@lgyhitler 我这样封装了下,应该没问题吧? 测了下 ,运行正常!
function Fn(){
return Promise.resolve()
.then(function(){
return redis.getAsync();
})
.then(function(val){
if(val) return db.findFromDB(sql);
return val;
});
}
//调用
Fn().then(function(val){
//输出结果
}).catch(function(error){
//处理错误
})
是的,没错
@imhered
redis.getAsync()
是返回 Promise 么? 如果是的话, 我觉得其实就不需要再写一遍 Promise.resolve()
了. Fn 直接从 return redis.getAsync()
开始就行.
另外, 你的 if(val) 是不是写反了? 有缓存的时候去执行 sql ?
@Chunlin-Li 嗯,是的。代码已经改过了,直接从return redis.getAsync()
开始的,if(val)
这个确实是写反了,不过只是提问的时候写反了的