首先,我知道进行同步通话是“错误的”,并且知道“不可能”。
但是,在一个很复杂的情况下(我不知道如何解释),我需要等待服务器的响应,我使用GWT-Platform命令实现GWT RPC调用。
我正在寻找某种“黑客”来做这件事。
提前致谢。
答案 0 :(得分:8)
通常,通过处理RPC请求的onSuccess()
函数中的内容,您将自动“等待来自服务器的响应”。所以我假设您要阻止当前运行的所有代码?由于JavaScript是单线程的,并不容易,因此没有睡眠功能可以暂停程序。
但可能是使用计时器的黑客做了你想要的事情:
Timer checkRPCResponse = new Timer() {
@Override
public void run() {
if (!serverResponseReceived) {
this.schedule(100);
} else {
proceedWithProgram();
}
}
};
checkRPCResponse.schedule(100);
如果this.schedule(100)
在上面的示例中有效,我还没有尝试过,但是你明白了,这是检查服务器是否每100毫秒响应一次。当然,您必须在serverResponseReceived = true
函数中设置onSuccess()
。在RPC之后立即调用计时器。
答案 1 :(得分:5)
有一个解决方案,但这并不容易(例如,您无法翻转单个参数以使其正常工作)。 GWT正在使用普通的JS XMLHttpRequest。在GWT中,有一个名为com.google.gwt.xhr.client.XMLHttpRequest的覆盖类型。此类用于通过HTTP向服务器发送请求。首先通过调用open方法初始化每个JS XMLHttpRequest。此方法的参数很少,但第三个参数指定请求是否应该是异步的。如果将其更改为false,则请求将是同步的。
但是GWT-RPC不直接使用这个类,它通过RpcRequestBuilder使用它,而且这个类也没有直接使用XMLHttpRequest,它使用的是RequestBuilder。
所以你需要做的是创建自定义版本的RpcRequestBuilder和RequestBuilder(它将使用XMLHttpRequest初始化为同步)。
您可以将RPCRequest构建器设置为GWT-RPC服务实例,方法是将其转换为ServiceDefTarget。
您是否仍希望获得同步GWT-RPC请求?
答案 2 :(得分:0)
GWT调用 XMLHttpRequest.open() whith为第三个参数,这意味着调用将是异步的。我解决了类似的测试需求,只是强迫第三个参数始终为false:
private static native void fakeXMLHttpRequestOpen() /*-{
var proxied = $wnd.XMLHttpRequest.prototype.open;
(function() {
$wnd.XMLHttpRequest.prototype.open =
function() {
arguments[2] = false;
return proxied.apply(this, [].slice.call(arguments));
};
})();
}-*/;
在调用 fakeXMLHttpRequestOpen()之后,XMLHttpRequest的任何进一步使用将同步执行。例如:
remoteSvc.getResult(new AsyncCallback<String>() {
@Override
public void onSuccess(String result) {
GWT.log("Service called!");
}
@Override
public void onFailure(Throwable caught) {
GWT.log("Service failed...");
}
}
GWT.log("Last message");
总是呈现:
Service called!
Last message
有关XMLHttpRequest.open()规范,请参阅https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open。