Google Web Toolkit(GWT)EventBus事件触发/处理

时间:2011-06-08 22:41:38

标签: ajax gwt gwt-rpc event-bus

背景故事:
我正在开发一个GWT应用程序,使用标准的MVP设计模式,并使用RPC从我的自定义数据处理servlet获取数据(在幕后做了很多)。无论如何,我的目标是创建一个非常简单的自定义缓存机制,它将从RPC回调返回的数据存储在静态缓存POJO中。 (回调还使用SimpleEventBus向所有已注册的处理程序发送自定义事件。)然后,当我再次请求数据时,我将在再次执行RPC服务器调用之前检查缓存。 (并使用EventBus发送自定义事件)。

问题:
当我从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回调中才能正常工作。我认为这是一个线程问题,但我搜索谷歌是徒劳的,任何有用的东西。

我有一个完整的Eclipse项目,展示了我遇到的这个问题,可以在以下网址找到:Eclipse Problem Project Example



编辑:请注意,使用eventBus.fireEventFromSource(...)仅用于调试目的,因为在我的实际GWT应用程序中,我有多个已注册的事件处理程序。那你如何正确使用EventBus

1 个答案:

答案 0 :(得分:1)

如果我正确理解您的问题,您希望将SimpleEventBus#fireEventFromSource的呼叫仅路由到source对象。事实并非如此 - 事件总线将始终向所有已注册的处理程序激活事件。一般来说,使用EventBus的目的是将事件源与其处理程序分离 - 基于事件source的功能与此目标背道而驰。

要获得您想要的行为,请将AsyncCallback传递给缓存RPC客户端,而不是尝试以非预期方式使用EventBus概念。这有一个额外的好处,即当RPC调用失败时警告Activity有问题:

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);
  }
});