2012-01-04 80 views
5

首先,我知道做同步調用是「錯誤的」,並且知道「不可能」。假GWT同步RPC調用

但是,在一個很複雜的情況下(我不知道如何解釋),我需要等待來自服務器的響應,我使用GWT-RPC命令實現了GWT RPC調用。

我正在尋找某種「黑客」來做這件事。

在此先感謝。

+3

不要這樣做。爲你的問題找到一個異步解決方案更好。 – 2012-01-04 16:16:13

+3

「首先,我知道做同步通話是」錯誤的「,並且知道」不可能「。」 – caarlos0 2012-01-04 16:19:05

+0

這是可能的,但這並不容易,你真的想這樣做嗎? – jusio 2012-01-04 16:54:28

回答

5

有一個解決方案,但它是不容易的(例如,你不能翻轉一個單一的參數,使其工作)。 GWT正在使用正常的JS XMLHttpRequest。在GWT中有一個覆蓋類型,稱爲com.google.gwt.xhr.client.XMLHttpRequest。該類用於通過HTTP向服務器發送請求。每個JS XMLHttpRequest首先通過調用方法open來初始化。此方法只有很少的參數,但第三個參數指定請求是否應該是異步的。如果將其更改爲false,則請求將同步。

但GWT-RPC不直接使用這個類,它通過RpcRequestBuilder使用它,而且這個類也不直接使用XMLHttpRequest,它使用的是RequestBuilder。

所以你需要做的是創造RpcRequestBuilder和RequestBuilder的定製版本(這將使用XMLHttpRequest初始化爲同步)。

的你可以設置RPCRequest建設者您的GWT-RPC服務實例,通過它鑄造於ServiceDefTarget。

你還想要同步GWT-RPC請求嗎?

+0

母親的上帝,努力工作。我放棄嘗試這樣做。我會把你的答案作爲現在的權利。不管怎麼說,還是要謝謝你。 – caarlos0 2012-01-04 17:35:10

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毫秒響應一次。當然你必須在onSuccess()函數中自己設置serverResponseReceived = true。在RPC之後立即調用計時器。

+0

我已經嘗試做這樣的事情,但它不工作,因爲我需要在吸氣。無論如何,我做了一個小的解決方法,在響應來自服務器之前調用一個事件,並且在演示者中,我需要信息,我再次更新所有的小部件。這不是我的問題的最佳解決方案,但是,我發現的唯一途徑... – caarlos0 2012-01-04 17:14:15

0

GWT調用XMLHttpRequest.open() whith作爲其第三個參數,這意味着該調用將是異步的。我解決了測試的目的只是迫使這第三個參數是始終虛假同樣需要:

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 

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open爲XMLHttpRequest.open()規範。