Gwt rpc AsyncCallbak 之后的代码不会被执行?

Posted

技术标签:

【中文标题】Gwt rpc AsyncCallbak 之后的代码不会被执行?【英文标题】:code after Gwt rpc AsyncCallbak will not be executed? 【发布时间】:2012-04-04 15:28:58 【问题描述】:

不明白为什么gwt rpc AsyncCallback之后的代码不会被执行?

例如,我有接口 AppService 扩展 RemoteService,所以我将有执行异步调用的 AsyncAppService。

以下代码

            AppServiceAsync service = GWT.create (AppService.class);
        service.getCurrentUser(new AsyncCallback<Employee>()

            public void onFailure(Throwable caught) 

            

            public void onSuccess(Employee result) 
                currentUser = result;
            

        );
 // if i have the code after the above call, these code will not be execute, what is the problem
//code following will not be executed if they are in the same function.
    boolean isAdmin = false;
        if(currentUser!=null)
            if(currentUser.getUserRole().equals("ROLE_ADMIN") ||
                    currentUser.getUserRole().equals("ROLE_MANAGER"))
                isAdmin = true;
            
        

感谢您的解释

【问题讨论】:

【参考方案1】:

您应该了解异步调用的性质。当您调用service.getCurrentUser 时,程序执行不会等待。程序将继续到下一行 (boolean isAdmin = false) 并且 在一段时间内 (currentUser == null) 直到方法 getCurrentUser 正在执行。您应该将未执行的代码块移动到 onSuccess 处理程序中

这个例子应该是这样的:

service.getCurrentUser(new AsyncCallback<Employee>()

    public void onFailure(Throwable caught) 

    

    public void onSuccess(Employee result) 
        currentUser = result;
        if (currentUser != null) 
            if (currentUser.getUserRole().equals("ROLE_ADMIN") ||
                currentUser.getUserRole().equals("ROLE_MANAGER")) 
                isAdmin = true;
            
        

    

);

我假设 currentUser 和 isAdmin 是类字段,但不是局部变量。如果 isAdmin 是本地的,那么您可以将此变量包装到最终数组中:final boolean[] isAdmin = new boolean[1] 并像 isAdmin[0] 一样调用它

【讨论】:

谢谢提醒,我没有意识到同步问题。但是这里有一个新的问题,如果函数是异步的,无论如何都会执行函数后面的代码,所以不会等待函数的结果?将变量包装到最终数组中是什么意思? currentUser 是一个类,但 isAdmin 是布尔值。 你是对的,如果函数是异步的,那么就不会等待结果。 Java 不支持闭包。所以在匿名类中你不能使用非最终局部变量。它不会被编译。 你的意思是,因为我使用的currentUser的属性不是final的局部变量,所以asynchro func后面关于类的代码不会被编译,以保护asyncro机制? 不,我不是这个意思。请阅读本文en.wikipedia.org/wiki/Closure_(computer_science),“内部类(Java)”部分。这里是关于异步调用的很好的解释code.google.com/p/google-web-toolkit-doc-1-5/wiki/… 应该不是很难理解,但无论如何你可以就这2篇文章提出问题。【参考方案2】:

假设您是过去非计算机化股票/商品市场的经纪人。让我们假设它以下列方式运行。

现在是星期一上午 9.30。您按顺序计划了这些。事实上,你的经验如此丰富,它已被编入你的内心:

程序 BuyAlBanySteel(500):

    您想打电话购买 500 AlbanySteel。 通过将在交易大厅循环的呼叫板。 当呼叫板返回报价并且报价对您来说是同意的, 接近要约人购买股票。

节目喝咖啡

    倒咖啡 喝咖啡。

您必须处理的警告:获得呼叫响应至少需要 10 分钟,甚至一个小时。它是异步的。您知道需要多长时间,但不确定。

所以这是你早上的计划:

    执行 BuyAlBanySteel(500) 喝咖啡。

让我问你,你会如何组织你的工作流程?你会这样构造吗?假设每个任务需要你一分钟的时间来执行。

9.31 am
Send offer(
  buy = 500 AlbanySteel
  messenger = annie
  When annie comes back, analyse offer.
  Pour Annie a cup of tea.
)

9.32 am
if (annie has an agreeable offer) buy 500 AlbanySteel.

9.33 am
Pour Coffee.

9.34
Drink Coffee.

当然不能。原因是下面这行

9.32 am
if (annie has an agreeable offer) buy 500 AlbanySteel.

将无法正确执行。它似乎没有被执行,因为安妮还没有回来提供报价。她可能需要再过 10 分钟或一个小时才能收到报价。

所以,这就是您执行工作流程的方式

9.31 am
Send offer(
  buy = 500 AlbanySteel
  messenger = annie
  when annie comes back,
  analyse offer.
  Pour Annie a cup of tea.
  if (annie has an agreeable offer) buy 500 AlbanySteel.
)

9.33 am
Pour Coffee.

9.34
Drink Coffee.

那么,在 GWT 伪代码中,你会选择执行哪一个?

你会执行这个吗:

BuyAlbanySteelAsync albanyService = GWT.create(BuyAlbanySteel.class);

albanyService.getOffer(
  new Task<Annie>()
    onFailure(Annie)Do nothing

    OnSuccess(Annie)
       analyse offer.
       Pour Annie a cup of tea.
    
  
);

if(Annie has agreeable offer)
  buy the stock.

或者这样:

BuyAlbanySteelAsync albanyService = GWT.create(BuyAlbanySteel.class);

albanyService.getOffer(
  new Task<Annie>()
    onFailure(Annie)Do nothing

    OnSuccess(Annie)
       analyse offer.
       Pour Annie a cup of tea.
       if(Annie has agreeable offer)
         buy the stock.
    
  
);

【讨论】:

你说的对,它帮助我理解了同步问题。但是这里有一个新的问题,如果函数是异步的,无论如何都会执行函数后面的代码,所以不会等待函数的结果? 尝试进行同步调用是个坏主意。您需要重新调整您的编程风格以适应异步编程,以获得有效和高效的 Web 应用程序。我不清楚浏览器上的 javascript 引擎背后是什么,但尝试同步调用会导致您的应用/页面的性能参差不齐。 使用同步调用会显着减慢(或有时阻止)应用程序接口对用户操作的反应,因为每次调用 RPC 时用户都在等待服务器响应。

以上是关于Gwt rpc AsyncCallbak 之后的代码不会被执行?的主要内容,如果未能解决你的问题,请参考以下文章

GWT Java rpc 调用工作;但是,替换 GWTBootstrap - rpc 调用不起作用

对于 GWT GAE Java 应用程序,这种 GWT/RPC 安全方法的安全性如何?

GWT RPC 未生成正确的 gwt.rpc 文件

如何使用 GWT-RPC 以外的方式访问 GWT servlet?

解码根据 GWT 的序列化策略生成的 *.gwt.rpc 文件

GWT - 偶尔出现 com.google.gwt.user.client.rpc.SerializationException