Nashorn将编译后的程序放入引擎范围内

问题描述 投票:0回答:1

我有两个js文件。

  • 一个是js库
  • 第二个是一个简单的脚本,通常大约50行,需要访问库中的函数。

在我的项目中,我试图在应用程序启动时预编译所有的javascripts,然后在运行时只调用CompiledScripts的所需参数。

我最终得到了以下代码



    static String LIBRARY = "function hello(arg) {return 'Hello ' + arg;};";

    static String SCRIPT = "hello(arg)";

    public static void main(String... args) throws Exception {
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("Nashorn");
        Compilable compilable = ((Compilable) engine);
        CompiledScript compiledLib = compilable.compile(LIBRARY);
        compiledLib.eval();

        CompiledScript actualScript = compilable.compile(SCRIPT);

        Bindings helloParams = new SimpleBindings();
        helloParams.put("arg","world");
        ScriptObjectMirror result = (ScriptObjectMirror) actualScript.eval(helloParams);
        System.out.println(result);
}

但这段代码会抛出一个错误

> compiledScript.eval(helloParams);
<eval>:1 ReferenceError: "hello" is not defined

我怎样才能从 "actualScript "中访问 "compiledLib "的上下文(即方法和变量)?

java nashorn scriptengine
1个回答
2
投票

编译时不注册 hello() 函数,它只是解析JavaScript代码。

你需要 执行 函数的代码。

请记住,在JavaScript中,这两个语句之间几乎没有什么区别,除了 function 声明是被挂起的,因此可以在声明语句之前使用。

function hello(arg) {return 'Hello ' + arg;};

var hello = function(arg) {return 'Hello ' + arg;};

因此没有什么理由单独编译LIBRARY代码, 你只需运行它并保存所有创建的全局变量, 也就是库方法. 例如,执行完你的LIBRARY代码后,你会有一个全局变量,名为 hello.


ScriptEngine engine = new ScriptEngineManager().getEngineByName("Nashorn");
Compilable compilable = ((Compilable) engine);

// Process LIBRARY code
Bindings bindings = new SimpleBindings();
engine.eval(LIBRARY, bindings);

// Compile SCRIPT code
CompiledScript actualScript = compilable.compile(SCRIPT);

// Run SCRIPT code
bindings.put("foo", "world");
Object result = actualScript.eval(bindings);
System.out.println(result);

产量

Hello world
© www.soinside.com 2019 - 2024. All rights reserved.