【问题标题】:URLLoader loads multi files and the result order is the same as call load()URLLoader 加载多个文件,结果顺序与调用 load() 相同
【发布时间】:2012-04-01 04:52:47
【问题描述】:

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

以下是代码sn-p:

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

【问题讨论】:

    标签: actionscript-3 apache-flex urlloader


    【解决方案1】:

    您可以扩展URLLoader 类功能。

    dynamic class DynamicURLLoader extends URLLoader { }
    

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

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

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

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

    【讨论】:

      【解决方案2】:

      你可以使用BulkLoader - 它有这个内置。或者你必须建立自己的队列,一个文件一个接一个地加载。

      代码sn-p:

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

      【讨论】:

      • BulkLoader 非常棒,谢谢。顺便说一句,您能分享一下您找到此类开源的经验吗?
      【解决方案3】:

      你可以像下面的例子一样依次加载每个 url:

      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.&lt;String&gt; 对象_urls 中加载一个url。它使用_counter 对象作为计数器,在每个UrlLoader 对象的“完成”事件发生时递增。

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

      【讨论】:

      • 谢谢,它有效。但是,如果请求很多,它的性能就会很差,对吧?
      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 2019-10-09
        • 2021-03-08
        • 1970-01-01
        • 2023-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-26
        • 2014-04-08
        相关资源
        最近更新 更多