Node.js中Redis事件处理函数丢失类实例引用问题求助
解决Node.js中Redis事件回调丢失类实例
this引用的问题 这个问题我之前也碰到过!当你把类的方法直接作为回调传给Redis的on方法时,JavaScript的函数执行上下文会发生变化——此时route方法里的this不再指向你的Test实例,而是指向触发事件的Redis订阅客户端对象(严格模式下甚至会变成undefined),所以你访问this.message才会得到undefined。
下面给你三种常用的解决方法,都能帮你把this正确绑定到Test实例上:
方法1:使用bind显式绑定this
bind方法会创建一个新函数,这个新函数的this会被永久绑定到你传入的对象上。修改redis.js里的事件监听代码:
// 把test.route绑定到test实例,确保回调执行时this指向实例 redisSubscriber.on('pmessage', test.route.bind(test))
这样当Redis触发pmessage事件时,route方法里的this就会一直指向test实例,this.message就能正确输出hello了。
方法2:用箭头函数包裹回调
箭头函数不会创建自己的this,它会继承外层作用域的this。这里外层作用域的this就是test实例所在的上下文,所以用箭头函数包裹test.route调用:
redisSubscriber.on('pmessage', (pattern, channel, message) => { test.route(pattern, channel, message) })
这种写法直观易懂,也能保证route方法里的this始终指向test实例。
方法3:在类构造函数中提前绑定方法
如果你希望Test类的route方法无论在哪里调用,this都指向实例,可以在构造函数里提前完成绑定:
修改test.js的Test类:
class Test { constructor () { this.message = 'hello' // 提前把route方法的this绑定到当前实例 this.route = this.route.bind(this) } route (pattern, channel, message) { console.log(this.message) // 现在会正确输出hello console.log(pattern + ' ' + channel + ' ' + message) } } module.exports = Test
这样在redis.js里直接用test.route作为回调就没问题了,不需要额外处理:
redisSubscriber.on('pmessage', test.route)
验证效果
不管用哪种方法,当你运行代码后,设置Redis键时,控制台都会输出:
hello __keyevent@*__:set __keyevent@0__:set key
内容的提问来源于stack exchange,提问作者Rash
相关产品推荐
相关产品推荐

