我正在尝试在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)
})
}
答案 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
有用,以后不再使用。