Asynchronous 带有AsyncCallback和SuggestOracle的GWT

Asynchronous 带有AsyncCallback和SuggestOracle的GWT,asynchronous,gwt,Asynchronous,Gwt,我使用对服务器(Tomcat)的“AsyncCallbacks”来查询数据库中的“resultsets”,它应该显示为“SuggestOracle”的结果 我的问题是,在输入字段中键入时,会触发几个“AsyncCallback”,但它们不会按照输入的顺序触发 例如: 如果我输入字符串“user1”,应该会触发5次回调。现在查看服务器日志: Dez 30, 2017 9:27:59 AM com.test.server.dispatch.actionhandlers.SuggestUsersAct

我使用对服务器(Tomcat)的“AsyncCallbacks”来查询数据库中的“resultsets”,它应该显示为“SuggestOracle”的结果

我的问题是,在输入字段中键入时,会触发几个“AsyncCallback”,但它们不会按照输入的顺序触发

例如: 如果我输入字符串“user1”,应该会触发5次回调。现在查看服务器日志:

Dez 30, 2017 9:27:59 AM com.test.server.dispatch.actionhandlers.SuggestUsersActionHandler execute
INFORMATION: Giving suggestinos for query u searching for contacts of user 136141
Dez 30, 2017 9:27:59 AM com.test.server.dao.UserDAO getSuggestions
INFORMATION: suggesting ... with query:u
Dez 30, 2017 9:28:00 AM com.test.server.dao.UserDAO getSuggestions
INFORMATION: query resulted in: 4 elements
Dez 30, 2017 9:28:00 AM com.test.server.dispatch.ActionExecutor execute
INFORMATION: com.test.entities.User(Id: 136141, Email: h@h.com) finished executing action com.test.services.dispatch.actions.SuggestUsersAction
Dez 30, 2017 9:28:01 AM com.test.server.dispatch.actionhandlers.SuggestUsersActionHandler execute
INFORMATION: Giving suggestinos for query user1 searching for contacts of user 136141
Dez 30, 2017 9:28:01 AM com.test.server.dao.UserDAO getSuggestions
INFORMATION: suggesting ... with query:user1
Dez 30, 2017 9:28:02 AM com.test.server.dao.UserDAO getSuggestions
INFORMATION: query resulted in: 1 elements
Dez 30, 2017 9:28:02 AM com.test.server.dispatch.ActionExecutor execute
INFORMATION: com.test.entities.User(Id: 136141, Email: h@h.com) finished executing action com.test.services.dispatch.actions.SuggestUsersAction
Dez 30, 2017 9:28:02 AM com.test.server.dispatch.actionhandlers.SuggestUsersActionHandler execute
INFORMATION: Giving suggestinos for query user searching for contacts of user 136141
Dez 30, 2017 9:28:02 AM com.test.server.dao.UserDAO getSuggestions
INFORMATION: suggesting ... with query:user
Dez 30, 2017 9:28:03 AM com.test.server.dao.UserDAO getSuggestions
INFORMATION: query resulted in: 4 elements
Dez 30, 2017 9:28:03 AM com.test.server.dispatch.ActionExecutor execute
INFORMATION: com.test.entities.User(Id: 136141, Email: h@h.com) finished executing action com.test.services.dispatch.actions.SuggestUsersAction
Dez 30, 2017 9:28:03 AM com.test.server.dispatch.actionhandlers.SuggestUsersActionHandler execute
INFORMATION: Giving suggestinos for query us searching for contacts of user 136141
Dez 30, 2017 9:28:03 AM com.test.server.dao.UserDAO getSuggestions
INFORMATION: suggesting ... with query:us
Dez 30, 2017 9:28:04 AM com.test.server.dao.UserDAO getSuggestions
INFORMATION: query resulted in: 4 elements
Dez 30, 2017 9:28:04 AM com.test.server.dispatch.ActionExecutor execute
INFORMATION: com.test.entities.User(Id: 136141, Email: h@h.com) finished executing action com.test.services.dispatch.actions.SuggestUsersAction
它首先查询“u”,然后查询“user1”,然后查询“user”,最后查询“us”

因此,请求没有按正确的顺序发送。 您知道如何以正确的顺序发送这些异步查询的技巧吗


我担心将“AsyncCallbacks”与“SuggestOracles”结合使用不是一个好主意。

您永远不应该假设异步回调会以任何特殊顺序触发。有许多因素会导致某些呼叫延迟,因此顺序可能是随机的

我最喜欢的方法是只保留最后一个回调。请注意,当您键入时,假设
user1
您收到5个服务器调用,但您只对
user1
结果感兴趣。以前的(如
us
use
等)可以(甚至应该)省略

因此,我将
AsyncCallback
扩展为
CancelableAsyncCallback

public abstract class CancelableAsyncCallback<T> implements AsyncCallback<T> {

    private boolean cancelled = false;

    public void cancel() {
        cancelled = true;
    }

    public boolean isCancelled() {
        return cancelled;
    }
}
公共抽象类CancelableAsyncCallback实现AsyncCallback{
私有布尔值=false;
公开作废取消(){
取消=真;
}
公共布尔值已取消(){
退货取消;
}
}
我跟踪最后一次回调并取消以前不需要的结果,如下所示:

if(lastCallback != null)
    lastCallback.cancel();

lastCallback = new CancelableAsyncCallback<Type>() {
    @Override
    public void onFailure(Throwable caught) {
        if(!isCancelled()) {
            // do the stuff
        }
    }

    @Override
    public void onSuccess(Type result) {
        if(!isCancelled()) {
            // do the stuff
        }
    }
};
if(lastCallback!=null)
lastCallback.cancel();
lastCallback=新的CancelableAsyncCallback(){
@凌驾
失败时的公共无效(可丢弃){
如果(!isCancelled()){
//动手
}
}
@凌驾
成功时公共无效(类型结果){
如果(!isCancelled()){
//动手
}
}
};

亚当斯的答案可能在很多情况下都适用。他绝对正确,您永远不能假设异步回调将以您期望的任何顺序处理

我以一种稍微不同的方式处理这个问题:在响应对象中,我还返回原始查询。然后,我可以检查响应是否仍然适用于客户端应用程序现在所处的状态

这将类似于:

callback = new AsyncCallback<Type>() {
@Override
public void onFailure(Throwable caught) {
    // handle error
}

@Override
public void onSuccess(Type result) {
    String originalQuery = result.getOriginalQuery();
    if (originalQuery.equals(oracleBox.getValue())) {
      // handle return values
    }
}
};
callback=new AsyncCallback(){
@凌驾
失败时的公共无效(可丢弃){
//处理错误
}
@凌驾
成功时公共无效(类型结果){
String originalQuery=result.getOriginalQuery();
if(originalQuery.equals(oracleBox.getValue())){
//句柄返回值
}
}
};