开发者

How do I determine which URLLoader failed programmatically?

I'm developing a flash application that is getting information from a remote server using a URLLoader. I have a function that will create a request for information based on the product ID. When there is an error, I want to fall back to an alt开发者_JAVA技巧ernate URL, but to create the alternate URL, I need to know the product ID. What is the best method to determine which URLLoader failed (and which product request failed) so that I can regenerate the new URL?

My functions are below:

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


Correct me if I'm wrong, but won't e.target or e.currentTarget be the URLLoader that failed?


You could wrap your error handler in a local variable (which describes a new function) so you can pass the ID to the method which receives the error event:

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


An alternative to wrapping the error handler in a closure or retrieving the id from the target would be writting a custom loader that hides the retry mechanism, so your could use it pretty much like if it were a normal loader.

Something like this (I just wrote this in notepad, so it probably has errors, but just to give you the idea...):

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

}

Then in your load function:

function loadData(productID:String):URLLoader {

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜