0

我有一个桌面 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);

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

我需要的是某种方式让我的 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 对象添加一个侦听器,以便在每次评估新表达式时触发。看起来这应该很简单,但我已经为此旋转了好几天。

有任何想法吗?

4

1 回答 1

0

nashorn 不支持(nashorn 编译的)脚本的这种“工具”。您可以实例化一个 Timer 或从脚本中生成一个单独的线程——并且计时器回调或线程的运行可以具有通过进行 Java 调用“ping”的脚本。

于 2014-09-02T04:30:52.670 回答