URLLoader加载多个文件,结果顺序与call load()相同

时间:2012-03-31 06:48:59

标签: actionscript-3 flex urlloader

由于URLLoader是异步的,如何确保来自服务器端的数据顺序与loader.load()调用相同?换句话说,totalResults中的数据顺序与url相关内容的顺序是一样的吗?

以下是代码段:

1.for each(var url in urls) {
    loadData(url);
}
2.private function loadData(url:String):void {
    var urlLoader:URLLoader = new URLLoader();
    urlLoader.addEventListener(Event.COMPLETE, completeHandler);
    var request:URLRequest = new URLRequest(url);
    urlLoader.load(request);
}
3.private function completeHandler(event:Event):void {
    var loader:URLLoader = URLLoader(event.target);
    var result:Object = loader.data;
    totalResults.push(result);// suppose totalResults is Array and a property in the class.
}

4 个答案:

答案 0 :(得分:3)

您可以扩展URLLoader类功能。

dynamic class DynamicURLLoader extends URLLoader { }

然后在请求之前将数据(在您的情况下可能是index)存储在loader对象中:

 var urlLoader:DynamicURLLoader  = new DynamicURLLoader();
 urlLoader.index = ...

回复后,检索该数据(在您的情况下为index):

var loader:DynamicURLLoader = DynamicURLLoader(event.target);
totalResults[ loader.index ] = loader.data;

答案 1 :(得分:2)

你可以使用BulkLoader - 它有这个内置版本。或者你必须建立自己的队列,其中一个文件是在另一个文件之后加载的。

代码段:

0.var queue:Array, totalResults:Array = [];
var urlLoader:URLLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, completeHandler);

1.for each(var url in urls) {
    loadData(url);
}

2.private function loadData(url:String):void {
    var request:URLRequest = new URLRequest(url);
    queue.push(request);
}

3.private function doQueue() {
    if (queue.length > 0) {
        var arr:Array = queue.splice(0,1);
        var req:URLRequest = arr[0] as URLRequest;
        urlLoader.load(req);
    }
    else {
        // queue done !
        trace(totalResults);
    }
}

4.private function completeHandler(event:Event):void {
    var loader:URLLoader = URLLoader(event.target);
    var result:Object = loader.data;
    totalResults.push(result);// suppose totalResults is Array and a property in the class.
    doQueue();
}

答案 2 :(得分:1)

您可以依次按顺序依次加载每个网址,如下例所示:

package 
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.net.URLLoader;
    import flash.net.URLRequest;

    public class Main extends Sprite 
    {
        private var _urls:Vector.<String>;
        private var _counter:int;

        private var _data:Array;

        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);

        }// end function

        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);

            _urls = Vector.<String>(["text1.txt", "text2.txt", "text3.txt" ]);
            _counter = 0;
            _data = [];

            loadNext();

        }// end function

        private function loadNext():void
        {
            var urlLoader:URLLoader = new URLLoader();
            urlLoader.addEventListener(Event.COMPLETE, onComplete);
            urlLoader.load(new URLRequest(_urls[_counter]));

        }// end function

        private function onComplete(event:Event):void
        {
            _data.push((event.target as URLLoader).data);

            if (_counter++ == (_urls.length - 1)) trace("complete"); 
            else loadNext();

        }// end function

    }// end class

}// end package

方法loadNext()onComplete()充当循环。调用loadNext()时,将URLLoader对象实例化,并在Vector.<String>对象_urls中加载网址。它使用_counter对象作为计数器,该计数器在每个UrlLoader对象的“完整”事件上递增。

当调用onComplete()事件处理程序时,它会将URLLoader对象加载的数据推送到名为_data的数组中。最后,if语句检查是否已加载所有url,如果没有,则递增计数器,如果是,则执行应用程序中的其余代码,在本例中为trace("complete");

答案 3 :(得分:1)

为什么不使用HTTPService,它允许您使用AsyncToken来确定哪个初始调用导致哪个初始结果?这样,你就不必在两次调用之间等待(性能下降意味着。)下面是一些关于它如何与Remoting一起工作的文档,类似http://flexdiary.blogspot.com/2008/11/more-thoughts-on-remoting.html。使用HttpService,您可以通过send()方法获取令牌。