我有一个桌面 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 对象添加一个侦听器,以便在每次评估新表达式时触发。看起来这应该很简单,但我已经为此旋转了好几天。
有任何想法吗?