2013-04-08 93 views
4

假设构造函数在代码的客户端部分(被转换为javascript的代码)中运行。 onSuccess的回调方法会修改类的实例变量。 回调被实现为匿名类,因此可以使用OuterClass.this访问外部类的实例。在构造函数中使GWT asynccallback安全吗?

通常在普通的Java中,我们不应该这样做,因为通过这样做,'this'引用可以在对象构造完成之前转义。

但是,当Java代码转换为Javascript时,它是否也适用?我认为JavaScript代码是由Web浏览器中的单个线程执行的,所以这不应该是一个问题(单线程=>没有可见性问题)?

回答

2

AsyncCallback本身就是一个类。在生产模式下发送RPC请求时,可以保证结果将通过XmlHttpRequest异步进入;在编译的JavaScript中,在构建完成之前,不可能泄漏引用,因为回调将在独立的JavaScript执行堆栈中调用。

但是,在gwt-dev模式下,应该是异步的事情并不总是如此。就我个人而言,我放弃了超级开发模式下的gwt-dev,并且只在我真正需要java调试器时才使用gwt-dev,所以我无法确定它是否可以免于构建问题(测试它和找出!)。

如果您未在构造函数中发送任何请求,您将100%安全。如果您随后以不安全的方式访问OuterClass.this,则仅创建异步回调将导致问题,无论涉及哪些类。

3

一方面,你是对的 - 问题不能由单独的线程触发,因为JavaScript是单线程的。

回调事件肯定会由事件处理程序处理,该事件处理程序在当前事件处理程序(构建当前对象的处理程序)完成后启动。所以他们只会看到完全构建的对象。

另一方面,您通常不需要线程来利用基本问题。这里有一个简单的例子:

final A a = new A(); 
final B b = new B(a); 
public class A { 

    private B b; 

    public void setB(final B b) { 
    this.b = b; 
    } 

    public void letBSaySomething() { 
    b.saySomething(); 
    } 
} 
public class B { 

    private A a; 
    private final int some; 

    public B(final A a) { 
    this.a = a; 
    a.setB(this); 

    a.letBSaySomething(); 
    some = 55; 
    a.letBSaySomething(); 
    } 

    public void saySomething() { 
    RootPanel.get().add(new Label("Hello " + some)); 
    } 
} 

这将导致输出

Hello 0 
Hello 55 

(虽然 '某些' 是最后的)。这在GWT(编译/未编译)和普通Java程序中都会发生。

相关问题