2011-01-06 48 views
2

我正在開發一個使用URLLoader從遠程服務器獲取信息的Flash應用程序。我有一個函數會根據產品ID創建信息請求。出現錯誤時,我想回退到替代網址,但要創建替代網址,我需要知道產品ID。確定哪個URLLoader失敗(以及哪個產品請求失敗)以便我可以重新生成新URL的最佳方法是什麼?如何確定哪個URLLoader程序失敗?

我的功能如下:

function loadData(productID:String):URLLoader { 
    var productURL:URLRequest = new URLRequest("/path/to/product/" + productID); 
    var dataLoader:URLLoader = new URLLoader(); 

    dataLoader.addEventListener(Event.COMPLETE, parseData); 
    dataLoader.addEventListener(IOErrorEvent.IO_ERROR, handleDataError); 
    dataLoader.load(productURL); 

    return dataLoader; 
} 

function handleDataError(e:IOErrorEvent) { 
    var productID:String = ???; 
    var altProductURL:URLRequest = new URLRequest("/alternate/path/to/product/" + productID); 
    var dataLoader:URLLoader = new URLLoader(); 

    dataLoader.load(altProductURL); 
} 

回答

4

你可以在一個局部變量包裝您的錯誤處理程序(它描述了一個新的功能),這樣你就可以通過ID來接收錯誤事件的方法:

function loadData(productID:String):URLLoader { 
    var productURL:URLRequest = new URLRequest("/path/to/product/" + productID); 
    var dataLoader:URLLoader = new URLLoader(); 

    var errHandler:Function = function(event:IOErrorEvent):void { 
    handleDataError(event, productID); 
    }; 

    dataLoader.addEventListener(Event.COMPLETE, parseData); 
    dataLoader.addEventListener(IOErrorEvent.IO_ERROR, errHandler); 
    dataLoader.load(productURL); 

    return dataLoader; 
} 

function handleDataError(e:IOErrorEvent, productID:String) { 
    var altProductURL:URLRequest = new URLRequest("/alternate/path/to/product/" + productID); 
    var dataLoader:URLLoader = new URLLoader(); 

    dataLoader.load(altProductURL); 
} 
+0

選擇了這一個,因爲它非常簡單,並以最少的代碼量優雅地回答問題。如果我需要使用這個長期計劃,或者如果我打算將它用於多個地方(例如跨不同項目),我可能會使用Juan的解決方案。 – Steropes 2011-01-12 20:53:59

+0

@Steropes,很高興它解決了。我同意 - 胡安的解決方案非常優雅,很好地隱藏了故障轉移功能。 – bedwyr 2011-01-12 22:08:11

7

糾正我,如果我錯了,但不會e.targete.currentTarget失敗的的URLLoader?

+0

+1非常正確。 – weltraumpirat 2011-01-06 22:39:24

2

另一種將錯誤處理程序封裝在閉包中或從目標中檢索ID的方法是寫一個隱藏重試機制的自定義加載程序,這樣就可以像使用普通加載程序那樣使用它。

像這樣的東西(我只是寫了這個在記事本中,那麼它可能有錯誤,但只給你的想​​法...):

public class ProductDataLoader extends EventDispatcher { 

    private var _paths:Array; 
    private var _id:String; 
    private var _state:int; 

    private var _loader:URLLoader; 
    private var _data:Object; 

    public function get data():Object { 
     return _data; 
    } 

    public function ProductDataLoader(id:String) { 
     _paths = [ 
      "/path/to/product/", 
      "/alternate/path/to/product/" 
     ]; 
     _id = id; 
     _state = -1; 

     _loader = new URLLoader(); 
     _loader.addEventListener(Event.COMPLETE, handleComplete); 
     _loader.addEventListener(IOErrorEvent.IO_ERROR, handleError); 

    } 

    public function load():void { 
     if(hasNextPath()) { 
      _loader.load(new URLRequest(getNextPath())); 
     } else { 
      // here, we ran out of paths to try 
      // you shouldn't get here unless you call loadProduct() 
        //  more than once. 
      // you should probably throw an error here, but that's up to 
     } 

    } 

    private function hasNextPath():Boolean { 
     return _state < _paths.length - 1; 
    } 

    private function getNextPath():String { 
     _state++; 
     return _paths[_state] + _id;  
    } 

    private function handleComplete(e:Event):void { 
     // redispatch the complete event 
     _data = _loader.data; 
     dispatchEvent(e); 
    } 

    private function handleError(e:Event):void { 
     if(hasNextPath()) { 
      loadProduct(); 
     } else { 
      // we tried all paths without success 
      // so we just redispatch the error event 
      dispatchEvent(e); 
     } 
    } 

} 

然後在您的負載功能:

function loadData(productID:String):URLLoader { 

    var productLoader:ProductDataLoader = new ProductDataLoader(productId); 
    dataLoader.addEventListener(Event.COMPLETE, parseData); 
    dataLoader.addEventListener(IOErrorEvent.IO_ERROR, handleDataError); 
    dataLoader.load(); 
} 
相關問題