我正在尝试为节点redis模块构建一个小的包装器库。
var redis = require('redis'),
client = redis.createClient();
module.exports = {
/*
* Time To Live
*
* Time in seconds the cache will remain in
* memory.
*/
ttl: 120,
/*
* Time To Refresh
*
* Time buffer in seconds when the cache should
* be refreshed. On a cache check, if the ttl
* is less than the ttr, the cache will be
* refreshed.
*/
ttr: 60,
/*
* Check Cache
*
* Middleware to check if the request is cached
* before executing the full request.
*/
check: function (req, res, next) {
var key = req.url.slice(1, req.url.length).replace('/', ':');
client.get(key, function (err, value) {
if (value !== null) {
res.send(value);
client.ttl(key, function (err, ttl) {
if (ttl < this.ttr) {
return next();
}
return;
});
} else {
return next();
}
})
},
/*
* Set Cache
*
* Takes a key and a value and stores it in redis.
* Also takes the full response object "res" and
* handles sending the response if it has not
* already been sent.
*/
set: function (url, value, res) {
var key = url.slice(1, url.length).replace('/', ':');
client.set(key, value);
client.expire(key, this.ttl);
if (!res.headersSent) {
res.send(value);
}
return;
},
/*
* Keygen Cache
*
* Takes a urls substring and creates a keyname
* in line with redis best practices
*/
keygen: function (url) {
var key = url.slice(0,1).replace('/', ':');
console.log(key);
return key;
}
};
我无法弄清楚如何正确使用'this'关键字。如果我尝试引用this.ttl或this.ttr或从module.exports对象中的另一个函数调用this.keygen它总是未定义。我应该使用什么结构来启用同一对象内部的引用函数?
答案 0 :(得分:2)
您的check
函数中嵌套了函数,因此this
- 关键字与内部函数上下文有关,而与您的对象无关。
第一个解决方案:
function (req, res, next) {
var _this = this;
var key = req.url.slice(1, req.url.length).replace('/', ':');
client.get(key, function (err, value) {
if (value !== null) {
res.send(value);
client.ttl(key, function (err, ttl) {
if (ttl < _this.ttr) {
return next();
}
return;
});
} else {
return next();
}
})
}
如果您使用该函数作为回调函数,请将对象绑定到回调函数,如下所示:
// replace "yourModule" with the name of your module
var yourModule = require('./yourModule.js');
// an example for expressjs (use get, post ... or something else)
app.get('/some/url', yourModule.check.bind(yourModule));
另一个解决方案是在您的模块中使用局部变量(这些仅在您的模块中可见 - &gt;这就是您想要的)。
这样更容易:
/*
* Time To Live
*
* Time in seconds the cache will remain in
* memory.
*/
var ttl = 120;
/*
* Time To Refresh
*
* Time buffer in seconds when the cache should
* be refreshed. On a cache check, if the ttl
* is less than the ttr, the cache will be
* refreshed.
*/
var ttr = 60;
/*
* Check Cache
*
* Middleware to check if the request is cached
* before executing the full request.
*/
var check = function (req, res, next) {
var key = req.url.slice(1, req.url.length).replace('/', ':');
client.get(key, function (err, value) {
if (value !== null) {
res.send(value);
client.ttl(key, function (err, ttl) {
if (ttl < ttr) {
return next();
}
return;
});
} else {
return next();
}
})
};
/*
* Set Cache
*
* Takes a key and a value and stores it in redis.
* Also takes the full response object "res" and
* handles sending the response if it has not
* already been sent.
*/
var set = function (url, value, res) {
var key = url.slice(1, url.length).replace('/', ':');
client.set(key, value);
client.expire(key, ttl);
if (!res.headersSent) {
res.send(value);
}
return;
};
/*
* Keygen Cache
*
* Takes a urls substring and creates a keyname
* in line with redis best practices
*/
var keygen = function (url) {
var key = url.slice(0,1).replace('/', ':');
console.log(key);
return key;
};
/**
* PUBLIC API
*/
module.exports = {
check: check,
set: set,
keygen: keygen
};
现在,因为您不依赖于模块的上下文,您可以简单地执行此操作:
// replace "yourModule" with the name of your module
var yourModule = require('./yourModule.js');
// an example for expressjs (use get, post ... or something else)
app.get('/some/url', yourModule.check);