【问题标题】:How do you invoke a method in a Nashorn CompiledScript?如何在 Nashorn CompiledScript 中调用方法?
【发布时间】:2015-11-21 23:30:24
【问题描述】:

我有以下有效的代码:

ScriptEngine jsEngine = ScriptEngineManager.new().getEngineByName("nashorn");
jsEngine.eval("some script");

jsEngine.invokeMethod(jsEngine.eval("foo"), "bar");

但我想使用预编译的脚本,这样我就不必每次需要运行它时都评估脚本,所以我正在尝试;

ScriptEngine jsEngine = ScriptEngineManager.new().getEngineByName("nashorn");
CompiledScript compiledJS = jsEngine.compile("some script");

但是我不确定如何处理 CompiledScript,我该如何调用方法?它显然没有实现 eval() 以外的任何东西:https://docs.oracle.com/javase/8/docs/api/javax/script/CompiledScript.html

【问题讨论】:

标签: javascript java nashorn scriptengine


【解决方案1】:

你调用了方法?

这里有几个例子:http://www.programcreek.com/java-api-examples/index.php?api=javax.script.CompiledScript


例子:

import java.util.*;
import javax.script.*;

public class TestBindings {
    public static void main(String args[]) throws Exception {
        String script = "function doSomething() {var d = date}";
        ScriptEngine engine =  new ScriptEngineManager().getEngineByName("JavaScript");
        Compilable compilingEngine = (Compilable) engine;
        CompiledScript cscript = compilingEngine.compile(script);

        //Bindings bindings = cscript.getEngine().createBindings();
        Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
        for(Map.Entry me : bindings.entrySet()) {
            System.out.printf("%s: %s\n",me.getKey(),String.valueOf(me.getValue()));
        }
        bindings.put("date", new Date());
        //cscript.eval();
        cscript.eval(bindings);

        Invocable invocable = (Invocable) cscript.getEngine();
        invocable.invokeFunction("doSomething");
    }
}

【讨论】:

  • 如何调用方法? CompiledScript 没有实现 Invocable。
  • 在您链接到的页面中没有单独提及 invokeMethod 或 invokeFunction。
  • 我更新了示例,我之前使用过类似的方法,但是我可以说它有点不直观。没有使用过最新的脚本引擎,但我认为它的工作方式类似。
  • 那么,你在ScriptEngine中调用invokeFunction,为什么需要CompiledScript呢?每次我想再次调用函数/方法时是否需要创建新的绑定?调用该方法会修改 ScriptEngine 本身吗?
  • 1) CompiledScript 消除了一些开销,如果你一遍又一遍地运行它,它会更快。调用可以在脚本内部发生,尤其是在递归函数的情况下。它不是不变性保证,而是像一个常量——如果您需要更改脚本,则需要重新编译。 +更多 2) 不,您可以调用“cscript.eval();”同样,但是,如果您想使用不同的又名可变参数,那么可以。每次都重新编译是没有意义的,因为它有更大的开销。 3)它会改变上下文。如果您的意思是这样,您可以重用具有不同绑定的脚本引擎
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-30
  • 1970-01-01
  • 1970-01-01
  • 2015-05-17
相关资源
最近更新 更多