2011-06-08 57 views
2

背景故事:
我正在開發一個使用標準MVP設計模式的GWT應用程序,並且還使用RPC從我的自定義數據處理servlet中獲取數據(做了很多幕後)。無論如何,我的目標是創建一個非常簡單的自定義緩存機制,它將RPC回調返回的數據存儲在靜態緩存POJO中。 (回調函數還會使用SimpleEventBus向所有註冊的處理程序發送自定義事件。)然後,當我再次請求數據時,我會在再次執行RPC服務器調用之前檢查緩存。 (還可以使用EventBus發送自定義事件)。

Google Web Toolkit(GWT)EventBus event firing/handling

問題:
當我從RPC回調發送事件時,一切正常。問題是,當我發送緩存對象時,將事件發送到RPC回調之外。出於某種原因,這個事件不會讓我註冊處理程序。下面是一些代碼:

public void callServer(final Object source) 
{ 
    if(cachedResponse != null) 
    { 
     System.err.println("Getting Response from Cache for: "+ source.getClass().getName()); 

     //Does this actually fire the event? 
     eventBus.fireEventFromSource(new ResponseEvent(cachedResponse),source); 

    } 
    else 
    { 
     System.err.println("Getting Response from Server for: "+ source.getClass().getName()); 
     service.callServer(new AsyncCallback<String>(){ 

      @Override 
      public void onFailure(Throwable caught) { 
       System.err.println("RPC Call Failed."); 
      } 

      @Override 
      public void onSuccess(String result) { 
       cachedResponse = result; 
       eventBus.fireEventFromSource(new ResponseEvent(cachedResponse),source); 
      } 
     }); 
    } 
} 


現在我有兩個活動,HelloActivity和GoodbyeActivity(摘自:GWT MVP code
他們還打印出消息時的處理程序被調用。無論如何,這是輸出我從日誌中獲得:(不正確)

Getting Response from Cache for: com.hellomvp.client.activity.HelloActivity Response in GoodbyeActivity from: com.hellomvp.client.activity.HelloActivity Getting Response from Cache for: com.hellomvp.client.activity.GoodbyeActivity Response in HelloActivity from: com.hellomvp.client.activity.GoodbyeActivity


我希望得到的是這樣的:

Getting Response from Cache for: com.hellomvp.client.activity.HelloActivity 
Response in HelloActivity from: com.hellomvp.client.activity.HelloActivity 
Getting Response from Cache for: com.hellomvp.client.activity.GoodbyeActivity 
Response in GoodbyeActivity from: com.hellomvp.client.activity.GoodbyeActivity 


我會得到這個如果將上面的代碼更改爲以下代碼,則預期輸出:(這次是整個文件...)

package com.hellomvp.client; 

import com.google.gwt.core.client.GWT; 
import com.google.gwt.event.shared.EventBus; 
import com.google.gwt.user.client.rpc.AsyncCallback; 
import com.hellomvp.events.ResponseEvent; 

public class RequestManager { 

private EventBus eventBus; 
private String cachedResponse; 
private HelloServiceAsync service = GWT.create(HelloService.class); 

public RequestManager(EventBus eventBus) 
{ 
    this.eventBus = eventBus; 
} 

public void callServer(final Object source) 
{ 
    if(cachedResponse != null) 
    { 
     System.err.println("Getting Response from Cache for: "+ source.getClass().getName()); 

     service.doNothing(new AsyncCallback<Void>(){ 

      @Override 
      public void onFailure(Throwable caught) { 
       System.err.println("RPC Call Failed."); 
      } 

      @Override 
      public void onSuccess(Void result) { 
       eventBus.fireEventFromSource(new ResponseEvent(cachedResponse),source); 
      } 
     }); 
    } 
    else 
    { 
     System.err.println("Getting Response from Server for: "+ source.getClass().getName()); 
     service.callServer(new AsyncCallback<String>(){ 

      @Override 
      public void onFailure(Throwable caught) { 
       System.err.println("RPC Call Failed."); 
      } 

      @Override 
      public void onSuccess(String result) { 
       cachedResponse = result; 
       eventBus.fireEventFromSource(new ResponseEvent(cachedResponse),source); 
      } 
     }); 
    } 
} 
} 


所以指出,唯一的變化是我創建了一個新的RPC調用,它什麼都不做,並且在它的回調中發送事件,而是使用緩存的數據,它會使應用程序按預期工作。

所以問題:
我做錯了什麼?我不明白爲什麼'eventBus.fireEvent(...)'需要在RPC回調中正常工作。我認爲這是一個線程問題,但是我一直無法搜索Google提供的任何幫助。 Eclipse Problem Project Example



編輯:

我有一個展示的是我在這個問題上的整個Eclipse項目,它可以在這裏找到請注意,使用eventBus.fireEventFromSource(...)只被用於調試,因爲在我的實際GWT應用程序中,我有多個註冊處理程序來處理事件。那麼如何正確使用EventBus

回答

1

如果我正確理解您的問題,您期望撥打SimpleEventBus#fireEventFromSource只能路由到source對象。事實並非如此 - 事件公交車總是將事件發送給所有註冊的處理程序。一般來說,使用EventBus的目標是將事件源與處理程序分離 - 基於事件的source的功能與此目標背道而馳。

要獲得想要的行爲,請將AsyncCallback傳遞給緩存RPC客戶端,而不是嘗試以非預期方式使用EventBus概念。這有問題提醒Activity的好處時,RPC調用失敗:

public class RequestManager { 
    private String cachedResponse = null; 
    private HelloServiceAsync service = GWT.create(HelloService.class); 

    public void callServer(final AsyncCallback<String> callback) { 
    if (cachedResponse != null) { 
     callback.onSuccess(cachedResponse); 
    } else { 
     service.callServer(new AsyncCallback<String>(){ 
     @Override 
     public void onFailure(Throwable caught) { 
      callback.onFailure(caught); 
     } 

     @Override 
     public void onSuccess(String result) { 
      cachedResponse = result; 
      callback.onSuccess(cachedResponse); 
     } 
     }); 
    } 
    } 
} 

而在Activity

clientFactory.getRequestManager().callServer(new AsyncCallback<String>() { 
    @Override 
    public void onFailure(Throwable caught) { 
    // Handle failure. 
    } 

    @Override 
    public void onSuccess(String result) { 
    helloView.showResponse(result); 
    } 
}); 
+0

我明白使用EventBus解耦事件的來源,從概念的處理程序,我只是使用fireEventfromSource進行調試,以找出事件發生的位置以及發生的位置。我需要使用EventBus將事件發送給所有處理程序,在我的實際應用程序中(這僅用於演示),有多個處理程序只適用於一個處理程序。 – napo 2011-06-09 13:52:57

相關問題