Vaadin - 通过executeJs 从 javascript 获取值

问题描述 投票:0回答:1

嗨我想调用一个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 有更好的解决方案吗?

javascript java vaadin
1个回答
0
投票

将返回值返回给服务器始终是异步的。这是因为当框架运行运行

executeJs
的应用程序逻辑时,会话锁被持有。框架甚至无法将要执行的 JS 发送到浏览器,直到锁被释放之后,即从事件处理程序返回后或其他任何触发使用
executeJs
语句运行代码块的地方。

这意味着你只需要接受你的逻辑被分成两个独立的部分。您可以在第一个块中的 UI 中显示占位符(例如微调器),然后在

then
回调中继续完成 UI 更新。

© www.soinside.com 2019 - 2024. All rights reserved.