2013-04-08 24 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程序中都會發生。

相關問題