我正在尝试将JS中的匿名函数传递回Java,我希望稍后由另一个线程调用它。问题是当代码在另一个线程的上下文中执行时,绑定会丢失。我写了一个小例子来演示这个问题。
//
// Get engine, create bindings object, execute script
//
ScriptEngineManager engineManager = new ScriptEngineManager();
ScriptEngine engine = engineManager.getEngineByName("nashorn");
SimpleBindings bindings = new SimpleBindings();
SomeObject thing = new SomeObject();
bindings.put("thing", thing);
engine.eval(src, bindings);
//
// JS source:
//
thing.print("Hello from main thread");
thing.timer(function(){
thing.print("Hello from the timer");
});
//
// SomeObject - intended to be called from JS to print to stdout,
// and to schedule some code to be run 100ms later
//
public class SomeObject {
public void print(String s) {
System.out.println(s);
}
public void timer(final Runnable f) {
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
f.run();
timer.cancel();
}
}, 100);
}
}
具体错误是:Exception in thread "Timer-0" <eval>:4 ReferenceError: "thing" is not defined
我想我理解为什么会发生这种情况,我的问题是如何正确实现这一点。 Nashorn是否提供了将脚本上下文绑定到当前线程的方法?或者,是否试图直接调用一个线程中创建的匿名函数来自另一个坏主意?