我只能看到有关nashorn中loadWithNewGlobal用法的简单参考。

我只是想知道如何使用loadWithNewGlobal在nashorn中执行JavaScirpt的大量内容。我的javascript内容将具有多个JS方法。

在简单的JavaScript内容下面,当使用loadWithNewGlobal时可以正常工作。

String script = new StringBuilder("var script = 'var i = 0;i += 1;i += 1;';")
                .append("function addition() {")
                .append("return loadWithNewGlobal({ name: \"addition\", script: script });")
//               .append("return load({ name: \"addition\", script: script });")
                .append("}").toString();


从上面的代码中,我了解到loadwithNewGlobal的script参数是一个js变量,最后的算术运算结果将能够通过使用callable方法来检索。

我尝试通过在脚本中加载一个简单的方法来尝试,但是得到了意外的结果。

    String script = new StringBuilder("var script= 'var a = function testFunction() { var i = 0;i += 1;i += 1; return i;}';")
                .append("function addition() {")
                .append("return loadWithNewGlobal({ name: \"addition\", script: script });")
//               .append("return load({ name: \"addition\", script: script });")
                .append("}").toString();


任何人都可以帮助我获得一些使用loadWithNewGlobal的很好的例子,以更好地理解或者关于如何使用loadWithNewGlobal执行大型js内容的任何想法?

更新更多详细信息:
我只想在并行线程Java环境(Java1.8)中执行大型Javascirpt内容。由于它是并行线程环境,请尝试使用loadWithNewGlobal以避免全局变量发生串扰。

下面的示例代码,我正在尝试并期望结果,如果所有10个线程中有5个。
但是获取类型转换异常,也由ScriptObjectMirror尝试,但无法获得预期的输出。

关于我在这里想念的任何想法吗?

import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

import jdk.nashorn.api.scripting.ScriptObjectMirror;



public class LoadWithNewGlobal {

    private static Invocable invocableEngine;
    private static ScriptEngine jsEngine;
    public static String customFunction() {


        String resultValue= null;
        try{
        ScriptEngineManager factory = new ScriptEngineManager();
        jsEngine = factory.getEngineByName("nashorn");
        StringBuffer scrFile = new StringBuffer();
        String scriptContent = "var a=function() { var i=1; i+=2; i+=2; return i+'';}; a;";
        scrFile.append("function testFunction() {");
        scrFile.append("var obj = loadWithNewGlobal({name:\"foo\", script : \""+scriptContent+"\" });");
        scrFile.append("return obj;}");

        System.out.println(scrFile.toString());
        jsEngine.eval(scrFile.toString());
        invocableEngine = (Invocable) jsEngine;

        Callable<String> newEncrypt = new Callable<String>() {
            public String call() {
                String val = null;
                try {
                    val = (String) invocableEngine.invokeFunction("testFunction");
            //      ScriptObjectMirror sobj =   (ScriptObjectMirror) invocableEngine.invokeFunction("testFunction");
            //      System.out.println("The foo Value is :"+sobj.get("foo"));

                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
                return val;
            }
        };

        ExecutorService executor = Executors.newCachedThreadPool();
        ArrayList<Future<String>> results = new ArrayList<Future<String>>();

        for(int i=0; i< 10; i++){
            //submit Callable tasks to be executed by thread pool
            //add Future to the list, we can get return value using Future
            results.add(executor.submit(newEncrypt));

        }


        for(Future<String> fut : results){
             System.out.println(new Date()+ "::"+fut.get().toString());
         }
         executor.shutdown();

        }catch(Exception e){
            e.printStackTrace();
        }
        return resultValue;
    }

    public static void main(String[] args) {
        System.out.println("Result :"+customFunction());
    }

}

最佳答案

这个问题对我来说不是很清楚。请注意,您正在使用函数值定义变量,因此整个脚本的计算结果为“未定义”(因为这是变量声明语句)
在以下修改中,我在var decl之后添加了“ a”。声明:

var obj = loadWithNewGlobal({
   name: "foo",
   script: "var a = function() { print('hello') }; a"
});

print(obj);
obj()


进行此更改后,函数对象将作为loadWithNewGlobal调用的值返回-可以调用它。

黑白之间的唯一区别是“ load”和“ loadWithNewGlobal”:后者创建一个新的ECMAScript全局作用域对象并评估其中的脚本,因此返回的值都是脚本对象“ mirrors”-但是将镜像像普通对象一样透明地对待越多越好。

10-07 18:35