javascript - 无法让此关键字在 Node 模块中工作

标签 javascript node.js

我正在尝试为 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/

相关文章:

java - CryptoJS.SHA1 与 MessageDigest.getInstance ("SHA-1").digest()

javascript - 这个数组真的需要传播语法吗?

javascript - 除了侧面导航栏之外,如何向我的网站添加内容(文字)?

javascript - JavaScript:当另一个音频样本正在播放时,如何停止和重新启动音频?

node.js - app.use() 和 app.get() 之间的路径处理方式不同

json - npm 启动错误,但 node index.js 可以工作

javascript - node.js http服务器如何获取连接数

javascript - NodeJS res.write 不起作用控制台工作

javascript - js 中有线程(某种)变量吗?

mysql - HTML5页面用node.js连接mysql数据库