嗨我想调用一个javascript函数并将结果返回给java。详细来说,我有一个传单地图组件,我调用 getBounds() 来获取视图的边界框 - 我想将此边界框传递回服务器端 java。
我知道这是一个异步调用。我找到了两种获得结果的方法。第一个:
String js = map.clientComponentJsAccessor();
PendingJavaScriptResult executeJs = UI.getCurrent().getPage().executeJs("return " + js + ".getBounds()");
executeJs.then(json -> System.out.println("Json: " + json.toJson()));
效果很好,打印出了预期的结果。不幸的是,我没有从 then 函数中的 lambda 中得到结果。
第二种方法是:
String js = map.clientComponentJsAccessor();
PendingJavaScriptResult executeJs = UI.getCurrent().getPage().executeJs("return " + js + ".getBounds()");
try {
String json = executeJs.toCompletableFuture().get().toJson();
System.out.println("Json:" + json);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
一开始看起来不错,但在执行过程中我收到一个 IllegalStateException 并显示以下消息: 无法阻止锁定会话的线程的值。这是因为当该线程持有会话锁时,无法处理传递值的请求。
我明白这意味着什么,但我不知道如何避免。
您能帮我解决方法 1 或 2 的问题吗?或者使用 vaadin api 有更好的解决方案吗?
将返回值返回给服务器始终是异步的。这是因为当框架运行运行
executeJs
的应用程序逻辑时,会话锁被持有。框架甚至无法将要执行的 JS 发送到浏览器,直到锁被释放之后,即从事件处理程序返回后或其他任何触发使用 executeJs
语句运行代码块的地方。
这意味着你只需要接受你的逻辑被分成两个独立的部分。您可以在第一个块中的 UI 中显示占位符(例如微调器),然后在
then
回调中继续完成 UI 更新。