Функция обработчика событий Redis теряет ссылку на класс - PullRequest
0 голосов
/ 17 мая 2018

В моем приложении NODEJS я подписываюсь на различные события redis.Для всех событий я хочу вызвать мой маршрутизатор, который имеет логику для маршрутизации запроса в зависимости от характера событий.Как вы можете видеть в моем файле redis.js, я регистрирую функцию для получения этих событий.

redisSubscriber.on('pmessage', test.route) <-- Function is an instance of class Test

Я использую node-redis.Когда node-redis вызывает мой метод route(), он теряет ссылку на свой объект, т. Е. Он не может получить доступ к this.Чтобы проиллюстрировать это, я пытаюсь получить доступ к this.message из метода route(), который был вызван node-redis при получении события.

Файл - test.js

class Test {
  constructor () {
    this.message = 'hello'
  }

  route (pattern, channel, message) {
    console.log(this.message) // Output: undefined
    console.log(pattern + ' ' + channel + ' ' + message) // Output: __keyevent@*__:set __keyevent@0__:set key
  }
}

module.exports = Test

Файл - redis.js

const Redis = require('redis')

let redis = Redis.createClient({
  host: 'localhost',
  port: 6379
})
let redisSubscriber = redis.duplicate()

let Test = require('./test')
let test = new Test()

redisSubscriber.on('pmessage', test.route)
redisSubscriber.psubscribe('__keyevent@*__:set')
redisSubscriber.psubscribe('__keyevent@*__:del')
redisSubscriber.psubscribe('__keyevent@*__:expired')

// Allow redis-subscriber to subscribe to all events.
setTimeout(function () {
  // When I set this key, a set event is generated.
  redis.set('key', 'value', function (error) {
    if (error) throw error

    // Allow set event to propagate, then quit redis.
    setTimeout(function () {
      redisSubscriber.unsubscribe()
      redisSubscriber.quit()
      redis.quit()
    }, 100)
  })
}, 100)

1 Ответ

0 голосов
/ 17 мая 2018

попробуйте использовать функцию-оболочку над test.route, поскольку функция обратного вызова redis использует глобальную область, и this не будет доступен в обратном вызове.

Заменить

redisSubscriber.on('pmessage', test.route)

с

redisSubscriber.on('pmessage',(pattern, channel, message) => {
   test.route(pattern, channel, message);
})
...