Asynchronous Updates
Environment.runLater() API 提供了一种机制,以安全地从 webforJ 应用程序中的后台线程更新用户界面。这一实验性功能支持异步操作,同时保持用户界面修改的线程安全。
实验性功能
此功能为实验性,未来版本可能会改变或删除。
AI skill available
The webforj-handling-timers-and-async skill can schedule timers, debouncers, and async work safely on the UI thread. After installing the webforJ AI plugin, ask your assistant:
- "Refresh this dashboard every 30 seconds."
- "Add a search-as-you-type debouncer."
- "Run this CPU-heavy work in the background and update the progress bar."
理解线程模型
webforJ 强制执行严格的线程模型,所有用户界面操作必须在 Environment 线程上进行。之所以存在这种限制,是因为:
- webforJ API 限制:底层的 webforJ API 绑定到创建会话的线程
- 组件线程亲和力:用户界面组件维护的状态不是线程安全的
- 事件分发:所有用户界面事件都在单个线程上按顺序处理
这种单线程模型防止竞争条件,并为所有用户界面组件维护一致的状态,但在与异步的、长时间运行的计算任务集成时则会带来挑战。
RunLater API
Environment.runLater() API 提供了两种调度用户界面更新的方法:
Environment.java
// 调度一个没有返回值的任务
public static PendingResult<Void> runLater(Runnable task)
// 调度一个返回值的任务
public static <T> PendingResult<T> runLater(Supplier<T> supplier)
这两种方法都返回一个 PendingResult,它跟踪任务完成情况并提供对结果或发生的任何异常的访问。
线程上下文继承
自动上下文继承是 Environment.runLater() 的关键特性。当在 Environment 中运行的线程创建子线程时,这些子线程自动继承使用 runLater() 的能力。
继承如何工作
从 Environment 线程中创建的任何线程自动可以访问该 Environment。这种继承会自动发生,因此您无需传递任何上下文或配置任何内容。
@Route
public class DataView extends Composite<Div> {
private final ExecutorService executor = Executors.newCachedThreadPool();
public DataView() {
// 此线程具有 Environment 上下文
// 子线程会自动继承上下文
executor.submit(() -> {
String data = fetchRemoteData();
// 可以使用 runLater,因为上下文已被继承
Environment.runLater(() -> {
dataLabel.setText(data);
loadingSpinner.setVisible(false);
});
});
}
}