URLLoader loads multi files and the result order is the same as call load()

守給你的承諾、 提交于 2019-12-23 03:21:42

问题


Since URLLoader is async, how to make sure the order of data from server side is the same as the loader.load() call? In other words, the data order in totalResults is the same order of url-related content?

Following is code snippet:

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.
}

回答1:


You can extend URLLoader class functionality.

dynamic class DynamicURLLoader extends URLLoader { }

Then store data ( in your case probably index ) in loader object, before requesting:

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

After response, retrieve that data ( in your case index ):

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



回答2:


you could either use BulkLoader - it got this build-in. or you have to build your own queue, where one file is loaded after the other.

code snippet:

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



回答3:


You can load each url sequentially one after the other in order like in the following example:

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

The methods loadNext() and onComplete() act as a loop. When loadNext() is called, an URLLoader object is instantiated and loads an url in the Vector.<String> object _urls. It uses the _counter object as a counter that is increment upon each UrlLoader object's "complete" event.

When the onComplete() event handler is called, it pushes the data loaded by the URLLoader object into an array called _data. Finally an if statement checks to see if all the urls have been loaded, if not, it increments the counter, if so, it executes the rest of the code in the application, in this case trace("complete");.




回答4:


Why not just use HTTPService, which allows you to use AsyncToken to determine which initial call resulted in which initial result? That way, you don't have to wait between calls (with the performance degradation that implies.) Here is some documentation about how it works with Remoting, which is similar http://flexdiary.blogspot.com/2008/11/more-thoughts-on-remoting.html . With HttpService, you get back the token as a result of the send() method.



来源:https://stackoverflow.com/questions/9953734/urlloader-loads-multi-files-and-the-result-order-is-the-same-as-call-load

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!