如何确定以编程方式失败的URLLoader?

时间:2011-01-06 21:21:06

标签: flash actionscript-3 error-handling

我正在开发一个使用URLLoader从远程服务器获取信息的Flash应用程序。我有一个函数,它将根据产品ID创建信息请求。当出现错误时,我想回到备用URL,但要创建备用URL,我需要知道产品ID。确定哪个URLLoader失败(以及哪个产品请求失败)以便我可以重新生成新URL的最佳方法是什么?

我的功能如下:

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

3 个答案:

答案 0 :(得分:7)

如果我错了,请更正我,但不会e.targete.currentTarget 失败的URLLoader?

答案 1 :(得分: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);
}

答案 2 :(得分: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();
}