逐步执行ScriptEngine评估的JavaScript代码

时间:2014-08-26 19:55:20

标签: java javascript multithreading scriptengine

我有一个桌面Java应用程序,本质上是一个多线程的调度程序。每个线程负责读取JavaScript文件并解释/评估JavaScript代码。 JavaScript脚本复杂地执行无限运行的任务,控制由父Java应用程序公开的Java对象。

我对此没有任何问题。我创建了一个线程,它读取相应的JavaScript文件,然后对其进行评估。类似的东西:

public class TaskThread extends Thread {
    ...
    public void run() {
        String theScriptCode = ReadMyJavascriptFileIntoAString("somescript.js");
        ScriptEngineManager engineManager = new ScriptEngineManager();
        engine = engineManager.getEngineByName("nashorn");
        scriptableObject = new MyScriptableObjectClass();
        engine.put("scriptableObject", scriptableObject);
        engine.eval(theScriptCode);
    }
    ...
}

somescript.js文件可能包含以下内容:

while (!isAFullMoon()) {
    scriptableObject.doSomething();
    scriptableObject.doSomethingElse();
}

因此,行:

engine.eval(theScriptCode);

......可以很长时间运行。

我需要的是每次在ScriptCode中评估新表达式/函数时通知我的TaskThread对象的某种方式。这是必要的,因为,因为engine.eval(theScriptCode)将运行很长时间,我希望ScriptEngine定期生成。

我可以通过使TaskThread对象对MyScriptableObjectClass()的实例可见来实现。类似的东西:

        ...
        scriptableObject = new MyScriptableObjectClass(this);
        engine.put("scriptableObject", scriptableObject);
        ...

然后,在MyScriptableObjectClass的定义中:

public class MyScriptableObjectClass {
    private TaskThread parentThread;

    public MyScriptableObjectClass(TaskThread t) {
        this.parentThread = t;
    }

    public void doSomething() {
        // do something
        parentThread.yield();
        ...
    }

    public void doSomethingElse() {
        // do something else
        parentThread.yield();
        ...
    }

似乎必须有一种更优雅的方式来做到这一点 - 特别是因为这只会让我在调用Java对象的方法时产生。 JavaScript可能会在很长一段时间内执行,而不会调用任何Java对象成员。

我想要的是能够做一些事情,例如在每次评估新表达式时为ScriptEngine对象添加一个监听器。看起来这应该是非常直接的,但我已经在这几天旋转我的轮子。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

此类"仪器仪表" nashorn不支持(nashorn编译)脚本。您可以实例化一个Timer或从脚本中生成一个单独的线程 - 并且计时器回调或线程的运行可以有脚本“ping”" ping"通过Java调用。