英文:
GWT, how to make EntryPoint class wait for AsyncCallBack
问题
我正试图使用GWT将一个Android应用程序转换成网站。这只是一个未来项目的想法。
我想做的是模仿Cursor功能。我可以通过创建一个类并模仿我想要使用的函数来做到这一点。
但是我遇到了一个问题:
我的用户界面在Cursor完全初始化之前就完成了其代码。
到目前为止,以下是它的工作原理。我在我的入口点的onModuleLoad中有以下代码:
Cursor cursor = databaseHelper.retrieveData("select * from '0-1'");
label.setText("Column-count: "+cursor.getColumnCount());
这会输出0,因为入口点在我的cursor类完全初始化之前不会等待。
我的retrieveData方法在这里:
Cursor retrieveData(String query){
return new Cursor(query);
}
我的Cursor类中的构造函数在这里:
Cursor(String sql) {
greetingService = GWT.create(GreetingService.class);
columns = new ArrayList<>();
rows = new ArrayList<>();
currentPosition = -1;
greetingService.greetServer(sql, new AsyncCallback<List<List<String>>>() {
@Override
public void onFailure(Throwable caught) {}
@Override
public void onSuccess(List<List<String>> result) {
if (!result.isEmpty()) {
columns = result.get(0);
if (result.size() > 1) {
rows.addAll(result.subList(1, result.size()));
}
}
}
});
}
我尝试过使用while循环停止UI活动,等待一个布尔值从true变为false(在AsyncCallback的onSuccess中设置为false),但UI活动被锁定,网站崩溃。
有人在这方面有解决方案吗?
英文:
I am attempting to convert an android app to a website using GWT. This was just an idea for a future-project.
What I want to do is mimic the Cursor function. I can do that just fine creating a class and just mimicking the functions I want to use.
But here is my issue:
My UI finishes its code before the Cursor is fully initialized.
Here's how it works so far. I have the following code in my onModuleLoad, in my entrypoint:
Cursor cursor = databaseHelper.retrieveData("select * from '0-1'");
label.setText("Column-count: "+cursor.getColumnCount());
This outputs 0, because the entrypoint does not wait for my cursor-class to fully initialize.
My retrieveData method is here:
Cursor retrieveData(String query){
return new Cursor(query);
}
And my constructor in the Cursor-class is here
Cursor(String sql) {
greetingService = GWT.create(GreetingService.class);
columns = new ArrayList<>();
rows = new ArrayList<>();
currentPosition = -1;
greetingService.greetServer(sql, new AsyncCallback<List<List<String>>>() {
@Override
public void onFailure(Throwable caught) {}
@Override
public void onSuccess(List<List<String>> result) {
if (!result.isEmpty()) {
columns = result.get(0);
if (result.size() > 1) {
rows.addAll(result.subList(1, result.size()));
}
}
}
});
}
I have tried stopping the UI-activity with a while-loop waiting for a boolean to go from true to false (set to false in the onSuccess of the AsyncCallback), but the UI-activity is just locked and the site crashes.
Does somebody have a solution here?
答案1
得分: 1
使用Promises。
如果你正在向后端服务发起HTTP请求,你可以使用Fetch API,它使用了promises,尽管更多是方便而非必需。
GWT的Elemental2库提供了对promises和fetch API的绑定。例如:
DomGlobal.fetch("http://example.com/bar?x=5")
.then(response -> response.json())
.then(jsonData -> {
parseDataAndUpdateUI(jsonData);
return null;
});
英文:
Use Promises.
If you are making a HTTP request to a backend service, you could use the Fetch API, which uses promises, though convenient rather than necessary.
GWT's Elemental2 library provides bindings to the promises and fetch API's. For example:
DomGlobal.fetch("http://example.com/bar?x=5")
.then(response -> response.json())
.then(jsonData -> {
parseDataAndUpdateUI(jsonData);
return null;
});
答案2
得分: 1
做这些服务器调用的时候,你也可以使用 domino-rest,它已经有了 Android 实现 domino-rest-android,如果要进行多个调用并等待它们完成,你可以尝试使用 domino-aggregator。
使用 domino-aggregator,你可以像下面这样做:
ContextAggregator.ContextWait<String> waitForString = ContextAggregator.ContextWait.create();
ContextAggregator.ContextWait<Integer> waitForInteger = ContextAggregator.ContextWait.create();
ContextAggregator.waitFor(waitForString, waitForInteger)
.onReady(() -> {
//当两个等待都被解决时将被调用。
});
waitForString.complete("some string");
waitForInteger.complete(5);
因此,你可以为服务器调用创建一个等待上下文,同时将 UI 的初始化移动到 onReady
方法中。
英文:
For doing those server calls you can also use domino-rest which already have an implementation for android domino-rest-android and to make several calls and wait for them to finish you could try using domino-aggregator
with domino-aggregator you can do something like the following
ContextAggregator.ContextWait<String> waitForString = ContextAggregator.ContextWait.create();
ContextAggregator.ContextWait<Integer> waitForInteger = ContextAggregator.ContextWait.create();
ContextAggregator.waitFor(waitForString, waitForInteger)
.onReady(() -> {
//will be called when both waits are resolved.
});
waitForString.complete("some string");
waitForInteger.complete(5);
so simply you could make a waiting context for the server call, meanwhile move the initialization of the UI into the onReady method.
答案3
得分: 1
两个答案都指出了解决你的问题的方法。它们还展示了另外两种 - 我认为是现代的 - 从服务器获取数据的方式。
你在以下代码中遇到的问题是:
Cursor cursor = databaseHelper.retrieveData("select * from '0-1'");
label.setText("Column-count: "+cursor.getColumnCount());
那个 'retrieveData' 调用了服务器,但不会等待服务器返回。这是异步调用的本质。
将 'label.setText("Column-count: "+cursor.getColumnCount());' 移动到 'onSuccess' 方法中,它就会起作用。
Cursor(String sql) {
greetingService = GWT.create(GreetingService.class);
columns = new ArrayList<>();
rows = new ArrayList<>();
currentPosition = -1;
greetingService.greetServer(sql, new AsyncCallback<List<List<String>>>() {
@Override
public void onFailure(Throwable caught) {}
@Override
public void onSuccess(List<List<String>> result) {
if (!result.isEmpty()) {
columns = result.get(0);
if (result.size() > 1) {
rows.addAll(result.subList(1, result.size()));
}
}
label.setText("Column-count: "+cursor.getColumnCount());
}
});
}
英文:
Both answers before point out the solution to your problem. And they show two more - and I think modern - ways to get data from the server.
Your problem with the following code is:
Cursor cursor = databaseHelper.retrieveData("select * from '0-1'");
label.setText("Column-count: "+cursor.getColumnCount());
that 'retrieveData' calls the server but does not wait until the server returns. That's the nature of asynchronous calls.
Move 'label.setText("Column-count: "+cursor.getColumnCount());' into the 'onSuccess'-method and it will work.
Cursor(String sql) {
greetingService = GWT.create(GreetingService.class);
columns = new ArrayList<>();
rows = new ArrayList<>();
currentPosition = -1;
greetingService.greetServer(sql, new AsyncCallback<List<List<String>>>() {
@Override
public void onFailure(Throwable caught) {}
@Override
public void onSuccess(List<List<String>> result) {
if (!result.isEmpty()) {
columns = result.get(0);
if (result.size() > 1) {
rows.addAll(result.subList(1, result.size()));
}
}
label.setText("Column-count: "+cursor.getColumnCount());
}
});
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论