我有一个桌面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对象添加一个监听器。看起来这应该是非常直接的,但我已经在这几天旋转我的轮子。
有什么想法吗?
答案 0 :(得分:0)
此类"仪器仪表" nashorn不支持(nashorn编译)脚本。您可以实例化一个Timer或从脚本中生成一个单独的线程 - 并且计时器回调或线程的运行可以有脚本“ping”" ping"通过Java调用。