假设我有一个这样的脚本:
function hello() {
var x = 42; // notice the closure over x in the success handler
stuffExecutor.execute({
success: function (result) { println("Success: " + (result + x)); },
failure: function (reason) { println("Failure: " + reason; }
});
println("Starting to execute stuff...");
}
我们假设stuffExecutor
是一个Java对象,它具有execute()
方法,并且具有我已经放入上下文的相应签名。
我可以想象实现execute()
方法将其操作推迟到hello()
脚本返回之后(从而打印"开始执行内容......"首先在成功之前或者失败),但从那里开始,我不知道如何在延迟执行完成后返回并调用处理程序。特别是,success
处理程序从x
函数关闭局部变量hello()
,因此我不知何故需要"返回"旧的上下文(或以其他方式存储以供以后使用)。
我将如何做到这一点?
答案 0 :(得分:0)
您可以采取许多方法,但我建议这样做是为了最大程度地保持清洁和每侧代码的清晰度。
我假设success
和failure
是字符串,但如果它们是其他的话,转换很简单。
在Java方面,制作您的API:
public class StuffExecutor {
public abstract static class Listener {
public abstract void success(String result);
public abstract void failure(String reason);
}
private void stuff(Listener listener) {
try {
String result = doIt();
listener.success(result);
} catch (Throwable t) {
listener.failure(t.getMessage());
}
}
public void execute(final Listener listener) {
new Thread(new Runnable() {
public void run() {
stuff(listener);
}
}).start();
}
}
现在在JavaScript方面:
function hello() {
var x = 42; // notice the closure over x in the success handler
stuffExecutor.execute(new JavaAdapter(Packages.my.package.StuffExecutor.Listener, {
success: function (result) { println("Success: " + (result + x)); },
failure: function (reason) { println("Failure: " + reason; }
}));
println("Starting to execute stuff...");
}
就像我说的,其他方法可行。您可以将函数直接传递给Java API(它们将显示为org.mozilla.javascript.Callable
),但是用于调用它们的Java语法会变得更加复杂和混乱。
请注意,1.7R4版本中的JavaAdapter存在一个错误(导致许多人要求1.7R5尚未发布)。这应该适用于任何其他版本的Rhino或GitHub上的当前版本。
请注意,result
和reason
在此方案中为java.lang.String
个对象,而非本机JavaScript字符串。在您的代码中,它没有区别,但如果您以后需要将它们用作JavaScript字符串,则可能需要使用String(result)
和String(failure)
转换它们。