【问题标题】:TypeError: instance[method].bind is not a function AdonisJsTypeError: instance[method].bind 不是函数 AdonisJs
【发布时间】:2019-12-31 12:30:04
【问题描述】:

我在 git here 上集成 MQTT-adonis 模块 adonis-mqtt respo 在 adonis-js 应用程序中,同时服务它会引发异常

TypeError: instance[method].bind 不是函数

任何人都可以指导为什么会出现这种情况。

//event.js

'use strict'
 const Event = use('Event');
const Mqtt = use('Mqtt');
// Listen to some Events of the library
Event.on('MQTT:Connected', 'Message.subscription')
Event.on('MQTT:Disconnected', 'Message.disconnected')

//Listeners/Message.js

class Message extends MqttListener {

get subscription () {
return 'Topic/Info'
 }

async handleMessage (message, wildcardMatches) {
  }

它似乎在这个块中抛出异常

//node_modules/adonis-mqtt/Mqtt/Mqtt.js

this.client.on('connect', this._handleConnect.bind(this)) //here at this line
    this.client.on('offline', this._handleDisconnect.bind(this))
    this.client.on('close', this._handleDisconnect.bind(this))
    this.client.on('end', this._handleDisconnect.bind(this))
    this.client.on('message', this._handleMessage.bind(this))

编辑:::

如何重现:

先决条件:

  • Node JS 最新版本 (here)
  • Adonis Js 最新版本 (here)

克隆这个:

更新:

从订阅函数中删除 get 时,它可以正常工作,但我无法在以下代码 sn-p 中获取所需的数据

//node_modules/adonis-mqtt/Mqtt/Mqtt.js

async _registerListener (file) {
    const filePath = path.join(this.listenersPath, file)
    let task
    try {
      task = require(filePath)
    } catch (e) {
      if (e instanceof ReferenceError) {
        debug(
          'Unable to import task class <%s>. Is it a valid javascript class?',
          file)
        return
      } else {
        throw e
      }
    }

    // Get instance of task class
    const taskInstance = ioc.make(task)
    if (!taskInstance.subscription || taskInstance.subscription === '') {
      console.error(`MqttListener ${file} does not have a subscription string!`)
    } else {
      this.client.subscribe(taskInstance.subscription) // here
      debug('Subscribed to topic %s', taskInstance.subscription)
      console.log('Subscribed to topic %s', taskInstance.subscription)
      this.listeners.push(taskInstance)
    }
  }

更新:2

应用中有两个文件夹,一个是Listeners,另一个是MqttListeners,它们都有相同的命名文件Test.js,它也强制保留这两个文件。但是,Listener 文件夹中存在的文件更改不会产生任何影响。但是,从 MqttListners 文件夹的文件中删除订阅功能中的 get 前缀和 handleMessage() 中的控制台消息似乎是完美的。接收已发布的主题信息

【问题讨论】:

  • 你能分享这个项目吗?所以我可以尝试重现问题
  • @CrBast 更新了重现问题的问题。

标签: javascript node.js mqtt adonis.js


【解决方案1】:

你的问题来了

// events.js
Event.on('MQTT:Connected', 'Message.subscription')

由此,您将 Message.subscription 方法绑定到 MQTT:Connected 事件(实际上,这发生在 node_modules/@adonisjs/fold/src/Ioc/index.js#L879 中)。

但是,您的 Message.subscription 不是普通函数,而是 getter。您无法绑定 getter,因为此 method syntax 不使用函数表达式。

因此,为了解决您的问题,您应该将 MQTT:Connected 事件绑定到其他方法,即

// events.js
Event.on('MQTT:Connected', 'Message.connection')

// Listeners/Message.js
class Message extends MqttListener {
  connection() {
     return 'test/#';
  }
}

或者干脆从您的subscription 方法中删除get 前缀

// Listeners/Message.js
class Message extends MqttListener {

  subscription () {
    return 'test/#';
  }
}

如果我的回答不够清楚或者您需要一些额外的信息,请告诉我。

更新: 看到一些证明它有效的证据

【讨论】:

  • 错误消失了。早先错误地从另一个类中删除了get
  • 太棒了。如果需要任何其他帮助,请告诉我
  • 是的,我需要。现在 mqtt 已连接并订阅了所有主题,因为我将其设置为 #,我将如何在控制器中获取主题消息
  • 类似的东西 -- Event.on('MQTT:onMessage', 'Test.handleMessage')
  • 据我了解(我对 AdonisJS 和 mqtt 模块不太熟悉),根据文档 (github.com/Morlack/adonis-mqtt/blob/HEAD/…),您可以使用任何事件名称,即 Mqtt.sendMessage('mytopic', 'My Message', {qos: 1}) 并以类似方式处理它async handleMessage (message, wildcardMatches) {} 其中第一个参数是消息数据。如果您使用第三方服务,您应该使用他们的文档来获取消息名称。如果您向我提供这些信息,我可以提供帮助。
猜你喜欢
  • 2018-09-28
  • 1970-01-01
  • 2021-08-17
  • 2019-12-08
  • 2018-01-10
  • 1970-01-01
  • 2019-10-30
  • 2014-03-05
  • 2019-12-13
相关资源
最近更新 更多