用于javascript事件处理程序的主机对象

时间:2019-02-03 13:54:04

标签: java graalvm graaljs

我想允许JavaScript使用类似的语法注册事件

object.on('eventName', (event) => {
  event.something();
});

event对象提供不同的方法,具体取决于'eventName'是什么(取决于我想为其添加处理程序的事件类型)。

我将需要为objectevent创建宿主对象,我假设object所需的类必须看起来像

public class Events {
  public void on(String eventName, X<FirstEvent> event) {
    // ...
  }

  public void on(String eventName, X<SecondEvent> event) {
    // ...
  }
}

如果有两种类型的事件。

但是我不知道如何让graalvm自动选择正确的on方法,并且我不知道第二个参数使用哪种类型(它必须是JavaScript匿名函数,必须接受一个特定类型的参数,并且以后必须由我的Java代码运行。)

如何存储JavaScript匿名函数

(event) => {
  event.something();
}

作为某种Java Runnable,并确保GraalVM根据第一个字符串参数的值知道要使用哪种on方法(因为传递的event对象对于不同的事件将有所不同)

我认为这可能是一个非常复杂的问题,我发现正确地措辞很棘手。

我想为JavaScript创建一种方法来注册事件处理程序,这些事件处理程序将在以后使用某些参数进行调用。

1 个答案:

答案 0 :(得分:0)

我不是100%知道这是否是问题所在,但我希望这会有所帮助。

为了使此代码段起作用:

object.on('eventName', (event) => {
  event.something();
});

可用于互操作性的最简单的Java类:

public class MyJavaClass { 
  public void on(String type, Consumer<Object> handler) {
  }
}

然后可以从JavaScript中使用if,例如:

const myJavaClassType = Java.type('MyJavaClass')
var object = new myJavaClassType();

object.on('X', (event) => { console.log(event) })

这将起作用,并且方法.on()将运行,并且您可以存储handler以便稍后使用。

在Java中,没有基于参数 value 的方法重载。因此,如果要基于eventName的值调用特定的处理程序,则需要自己编写。

也许是这样的:

public class MyJavaClass { 
  private Map<String, Consumer<Object>> handlers = new HashMap<>();

  public void fire(String type, Object event) { 
    Consumer<Object> handler = handlers.get(type);
    if(handler != null) { 
        handler.accept(event);
    }
  }

  public void on(String type, Consumer<Object> handler) {
      handlers.put(type, handler);
  }