Javascript JSR-223:如何将可变主机函数绑定到ScriptEngine

Javascript JSR-223:如何将可变主机函数绑定到ScriptEngine,javascript,java,jsr223,scriptengine,graalvm,Javascript,Java,Jsr223,Scriptengine,Graalvm,我试图通过Java虚拟机下的JSR-223ScriptEngine运行Javascript,以调用用户提供的代码并向其传递一个“承诺式”回调:即一个不接受任何参数的函数(无值成功完成);单个参数(null用于无值或错误对象的成功完成);或两个参数(null对于成功完成,一个值) 我使用GaalVM实现这一点,并将回调放入Javascript绑定对象中。大概是这样的: var engine=new ScriptEngineManager().getEngineByName(“graal.js”);

我试图通过Java虚拟机下的JSR-223
ScriptEngine
运行Javascript,以调用用户提供的代码并向其传递一个“承诺式”回调:即一个不接受任何参数的函数(无值成功完成);单个参数(
null
用于无值或错误对象的成功完成);或两个参数(
null
对于成功完成,一个值)

我使用GaalVM实现这一点,并将回调放入Javascript绑定对象中。大概是这样的:

var engine=new ScriptEngineManager().getEngineByName(“graal.js”);
var binding=engine.getBindings(ScriptContext.engine\u范围);
binding.put(“导出”,engine.eval(“新对象()”);
engine.eval(用户代码,绑定);
绑定。放置(“数据”,数据);
binding.put(“callback”,callback);
engine.eval(“exports.handler(数据,回调)”,绑定;
问题是我不知道将什么作为
“回调”
绑定:

我试过简单的方法:

BiFunction回调=(err,value)->{/*…*/};
在这种情况下,使用两个参数调用回调可以正常工作,但使用一个参数(或没有参数)会出现错误:

org.graalvm.polyglot.PolyglotException: TypeError: EXECUTE on 
  JavaObject[my.package.JavascriptRun$$Lambda$771/0x0000000840844040@4cf04c6a 
  (my.package.JavascriptRun$$Lambda$771/0x0000000840844040)] failed due to: 
  Arity error - expected: 2 actual: 1
我尝试过获得一个
对象
数组,如下所示:

函数回调=(args)->{/*…*/};
这让GraalVM把这个扔给了我:

org.graalvm.polyglot.PolyglotException: TypeError: EXECUTE on
   JavaObject[my.package.JavascriptRun$$Lambda$771/0x0000000840844040@855ef90 
  (my.package.JavascriptRun$$Lambda$771/0x0000000840844040)] failed due to:
  java.lang.ClassCastException: class com.oracle.truffle.polyglot.PolyglotMap
  cannot be cast to class [Ljava.lang.Object; 
  (com.oracle.truffle.polyglot.PolyglotMap is in unnamed module of loader 'app';
   [Ljava.lang.Object; is in module java.base of loader 'bootstrap')
我目前正在考虑在Javascript中进行手动多重分派-基本上定义多个回调主机函数,然后在Javascript中检查参数的数量并相应地分派:

engine.eval(“exports.handler(数据,函数(){”+
“开关(参数.长度){”+
“案例0:返回回调0();”+
“案例1:返回回调1(参数[0])+
默认值:返回回调2(参数[0],参数[1])+
"} })");
但这对我来说似乎是个坏主意

MyCallback callback = (arguments) -> { /*...*/ };
在哪里

我想这对你有用

@FunctionalInterface
public static interface MyCallback {
    Object call(Object... arguments);
}