我正在尝试为 Node 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 ,它总是显示为未定义。我应该使用什么结构来启用同一对象内部的引用函数?
最佳答案
您的 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();
}
})
}
如果您将该函数用作回调函数,则将对象绑定(bind)到回调函数,如下所示:
// 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));
另一个解决方案是在模块中使用局部变量(这些变量仅在您的模块中可见 -> 这就是您想要的)。
这更容易:
/*
* 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);
关于javascript - 无法让此关键字在 Node 模块中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26537319/