代码场景大致如下。要从redis里获取一个结果集列表,获取的时候先判断是否存在缓存,如果没的话先设置缓存再调用。先贴下函数声明的代码。
exports.totalRank = function () {
var trDeferred = Q.defer();
Q.all([
RedisDB.getDailyRankList(),
RedisDB.getWeeklyRankList(),
RedisDB.getMonthlyRankList()
]).done(function (result) {
if(cacheExistsChecker(result)){
var returnResult = {
dailyRank: JSON.parse(result[0])[0].rank,
weeklyRank: JSON.parse(result[1])[0].rank,
monthlRank:JSON.parse(result[2])[0].rank,
}
trDeferred.resolve(returnResult);
}else{
CacheAction.setRanksLists().then(function(){
RankAction.totalRank().then(function(result){
trDeferred.resolve(result);
})
});
}
})
return trDeferred.promise;
}
调用该函数的代码如下:
RankAction.totalRank().then(function(result){
console.log(result);
}).fail(function(err){
console.log(err);
});
调用该方法时候,缓存不存在,所以肯定是进入了else的流程。
现在疑惑就是:
重点关注函数声明那段代码,else里面的RankAction.totalRank().then()里面的trDeferred,该对象是第一次调用就return了的promise对象,还是第一次判断缓存不存在,然后再重新调用totalRank时候重新var的trDeferred?
个人的理解是第一次的trdeferred。因为如果这里不用RankAction.totalRank().then(xxxx),而是直接RankAction.totalRank(),则不返回结果。
求分析解惑一下。
既然已经用了
all
,就没必要再构造defer
绕一圈了顺便说说题主代码里的另外几个问题
try{ dangerousAction() }catch{ //donothing }
是差不多的概念。调试噩梦exports
就是RankAction
(所以才会有调用自己之类的)。那么为啥缓存不命中的时候要调自己走一下命中的分支呢?结果的话不用额外调用,在自己的scope里面就有result啊CacheAction
为啥都没有接收到查询结果result
? 无论实际上怎么传值过去 ,这样的耦合都不妙。显式要好于隐式&全局变量是恶魔cacheExistsChecker
就是负责检查缓存是否命中的判断,把对应的if语句放在get
后面的话,这完全称不上是缓存,无论命中与否都会查redis了啊……缓存读的伪代码一般是return cacheHit() ? cacheGet() : (cacheSet(result = dbGet()), result)
是否hit肯定要最早就判断嘛