我正在寻找一种在调用异步服务时自动显示和隐藏“正在加载”消息的方法,所以与其这样做:
showLoadingWidget();
service.getShapes(dbName, new AsyncCallback() {
public void onSuccess(Shape[] result) {
hideLoadingWidget();
// more here...
}
public void onFailure(Throwable caught) {
hideLoadingWidget();
//more here
}
});
我想这样做,但仍然在完成时显示和隐藏消息。
// this should be gone: showLoadingWidget();
service.getShapes(dbName, new AsyncCallback() {
public void onSuccess(Shape[] result) {
// this should be gone: hideLoadingWidget();
// more here...
}
public void onFailure(Throwable caught) {
//this should be gone: hideLoadingWidget();
//more here
}
});
简而言之,我想改变异步调用的行为。感谢您的所有可能的建议。
丹尼尔
发布于 2009-08-21 12:16:17
您可以将调用本身包装在一个对象中,该对象处理加载消息的显示,可能会在出现错误时重试几次,等等。如下所示:
public abstract class AsyncCall<T> implements AsyncCallback<T> {
/** Call the service method using cb as the callback. */
protected abstract void callService(AsyncCallback<T> cb);
public void go(int retryCount) {
showLoadingMessage();
execute(retryCount);
}
private void execute(final int retriesLeft) {
callService(new AsyncCallback<T>() {
public void onFailure(Throwable t) {
GWT.log(t.toString(), t);
if (retriesLeft <= 0) {
hideLoadingMessage();
AsyncCall.this.onFailure(t);
} else {
execute(retriesLeft - 1);
}
}
public void onSuccess(T result) {
hideLoadingMessage();
AsyncCall.this.onSuccess(result);
}
});
}
public void onFailure(Throwable t) {
// standard error handling
}
...
}
要使调用执行类似如下的操作:
new AsyncCall<DTO>() {
protected void callService(AsyncCallback<DTO> cb) {
DemoService.App.get().someService("bla", cb);
}
public void onSuccess(DTO result) {
// do something with result
}
}.go(3); // 3 retries
您可以使用代码来扩展此功能,以检测耗时较长的呼叫,并显示某种忙碌指示器等。
发布于 2012-12-18 21:31:19
下面的AsyncCall
是我目前使用的(灵感来自David Tinker的解决方案)。这不是重试,而是期望某些RPC调用需要很长时间才能返回,如果调用在指定的超时之前没有返回,则会显示一个加载指示器。
此AsyncCall
还跟踪当前正在进行的RPC调用的数量,并且仅当所有RPC调用都已返回时才隐藏加载指示符。使用David的解决方案,加载指示器可能会被先前返回的RPC调用所隐藏,即使另一个调用仍在进行中。如果课程假设加载指示器小部件对于应用程序是全局的,在我的例子中就是全局的。
public abstract class AsyncCall<T> {
private static final int LOADING_TOLERANCE_MS = 100;
private static int loadingIndicatorCount = 0;
private Timer timer;
private boolean incremented;
private boolean displayFailure;
public AsyncCall(boolean displayFailure) {
this.displayFailure = displayFailure;
timer = new Timer() {
@Override
public void run() {
if (loadingIndicator++ == 0)
// show global loading widget here
incremented = true;
}
};
timer.schedule(LOADING_TOLERANCE_MS);
call(new AsyncCallback<T>() {
@Override
public void onSuccess(T result) {
timer.cancel();
if (incremented && --loadingIndicatorCount == 0)
// hide global loading widget here
callback(result);
}
@Override
public void onFailure(Throwable caught) {
timer.cancel();
if (incremented && --loadingIndicatorCount == 0)
// hide global loading widget here
if (AsyncCall.this.displayFailure)
// show error to user here
}
});
protected abstract void call(AsyncCallback<T> cb);
protected void callback(T result) {
// might just be a void result or a result we
// wish to ignore, so do not force implementation
// by declaring as abstract
}
}
发布于 2010-02-23 21:27:29
完整示例(Robert)
public abstract class AsyncCall<T> implements AsyncCallback<T>
{
public AsyncCall()
{
loadingMessage.show();
}
public final void onFailure(Throwable caught)
{
loadingMessage.hide();
onCustomFailure(caught);
}
public final void onSuccess(T result)
{
hideLoadingMessage();
onCustomSuccess(result);
}
/** the failure method needed to be overwritte */
protected abstract void onCustomFailure(Throwable caught);
/** overwritte to do something with result */
protected abstract void onCustomSuccess(T result);
}
https://stackoverflow.com/questions/1309436
复制相似问题