问题
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