带Scala.js的Vertx Eventbus客户端

时间:2017-06-22 21:08:48

标签: vert.x scala.js scalajs-react

我正在尝试在Scala.js项目中创建一个新的Vertx Eventbus实例。无论我做什么,在尝试在onopen函数中注册处理程序时都会得到INVALID_STATE_ERR。

似乎onopen过早被解雇了。

示例代码: Eventbus.scala:

@js.native
@JSImport("vertx3-eventbus-client",JSImport.Default)
class Eventbus(url:String) extends js.Any{

def registerHandler(address:String,callback:
(js.Dynamic,js.Dynamic)=>Unit): Nothing =js.native

var onopen:Unit=js.native

}

然后,从我的应用程序中,我称之为:

    val eb = new Eventbus("http://localhost:8080/eventbus")
    eb.onopen={
    println("opening")
    eb.registerHandler("activity-updates", (err, mess) => {
      val message = mess.body.toString
      println(message)
    })
  }

1 个答案:

答案 0 :(得分:0)

您输入onopen是错误的。应该是js.Function0[Unit]

onopen中的代码会立即执行(而不是“打开”)。

更改为:

var onopen: js.Function0[Unit]=js.native

eb.onopen={ () =>
println("opening")
eb.registerHandler("activity-updates", (err, mess) => {
  val message = mess.body.toString
  println(message)
})

registerHandler立即执行的原因是Scala(通常)允许在表达式位置使用语句(因此阻塞)。

因此,如果我们只看ep.onopen的作业:

eb.onopen={
  println("opening")
  eb.registerHandler("activity-updates", (err, mess) => {
    val message = mess.body.toString
    println(message)
  })
}

这会将右侧(值Unit)的块结果分配给eb.onopen。实际上这意味着语句执行如下:

println("opening")
val tmp = eb.registerHandler("activity-updates", (err, mess) => {
  val message = mess.body.toString
  println(message)
})

eb.onopen=tmp

因此,您甚至可以在registerHandler被分配之前看到onopen被执行。此功能(表达位置中的语句)当然对返回Unit的内容很少有用。但是,有些情况下非常有用。例如,临时工:

val x = {
  val myHelper = ???
  if (myHelper) ???
  else ???
}

现在myHelper在范围内没有逃脱,很明显它只对计算x有用,以后不再使用。