【问题标题】:JSR-223: How to bind a variadic host function to ScriptEngineJSR-223:如何将可变参数主机函数绑定到 ScriptEngine
【发布时间】:2019-03-26 15:26:44
【问题描述】:

我正在尝试通过 Java VM 下的 JSR-223 ScriptEngine 运行 Javascript,以调用用户提供的代码并将其传递给“promise-style”回调:即一个不接受任何参数的函数(成功完成没有价值);单个参数(null 成功完成,没有值或错误对象);或两个参数(null 表示成功完成,一个值)。

我为此使用 GaalVM,并将我的回调放入 Javascript 绑定对象中。像这样的:

var engine = new ScriptEngineManager().getEngineByName("graal.js");
var binding = engine.getBindings(ScriptContext.ENGINE_SCOPE);
binding.put("exports", engine.eval("new Object()"));
engine.eval(userCode, binding);
binding.put("data", data);
binding.put("callback", callback);
engine.eval("exports.handler(data, callback)", binding);

问题是我不知道该放什么作为"callback" 绑定:

我尝试了简单的方法:

BiFunction<Object, Object, Object> callback = (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

我试过像这样得到一个Object 数组:

Function<Object[], Object> callback = (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(data, function() { "+
  "switch(arguments.length) { "+
  "case 0: return callback0(); "+
  "case 1: return callback1(arguments[0]); "+
  "default: return callback2(arguments[0],arguments[1]); "+
  "} })");

但这对我来说似乎是个坏主意。

【问题讨论】:

    标签: javascript java jsr223 scriptengine graalvm


    【解决方案1】:
    MyCallback callback = (arguments) -> { /*...*/ };
    

    在哪里

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

    我猜对你有用。

    【讨论】:

      猜你喜欢
      • 2023-03-16
      • 2016-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-24
      • 1970-01-01
      • 1970-01-01
      • 2011-07-31
      相关资源
      最近更新 更多