为什么在使用多个URLLOADER上传时会被阻止?

时间:2011-09-19 03:48:17

标签: flash actionscript urlloader

我想上传包含多个 URLLOADER 的图片,这样我就可以节省等待COMPLETE_EVENT的时间。

有时它可能会被阻止,并且它不会给出完成事件,不会给出安全性错误,不会给出状态事件并且不会抛出异常。它根本不会发射任何事件。

private const RO_NUMBER:int = 2;
private var roPool:Array = new Array();

public function init():void {

        for (var i:int = 0; i < RO_NUMBER; i++) {

           loader:URLLoader = new URLLoader();
           loader.dataFormat = URLLoaderDataFormat.TEXT;
           loader.addEventListener(Event.OPEN, onStartUpload);
           loader.addEventListener(Event.COMPLETE, completeHandler);
           loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
           loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
           loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);

           roPool.push(loader);
        }
    }

public function startUpload(pictures:ArrayList):void {
        _pictures.addAll(pictures);
        init();
        if (getExternalInfo()) {
            for (var i:int = 0; i < RO_NUMBER; i++) {
                var loader = roPool.pop();

                loader.load(getRequest());
            }
        } else {
            onUploadFinish();
        }
    }

加载操作是异步的,单线程。为什么这会被阻止?

2 个答案:

答案 0 :(得分:1)

  

基于此版本的答案:
  https://stackoverflow.com/revisions/7466248/1

从我在代码中看到的内容中,您在循环的每次迭代中都使用了相同的URLLoader实例。

您需要创建URLLoader的新实例并将其添加到数组roPool中,因为此刻您正在重复执行相同的操作URLLoader

public function init():void
{
    for(var i:int = 0; i<RO_NUMBER; i++)
    {
        var ldr:URLLoader = new URLLoader();

        ldr.dataFormat = URLLoaderDataFormat.TEXT;
        ldr.addEventListener(Event.OPEN, onStartUpload);
        ldr.addEventListener(Event.COMPLETE, completeHandler);
        ldr.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
        ldr.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
        ldr.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);

        roPool.push(ldr);
    }
}

新答案:

尝试创建一个队列,一次只有一个URLLoader实例,粗略的例子:

类别:

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

    public class LoadQueuer extends Object
    {
        // Queue
        private var _queue:Array = [];

        /**
         * Standard load
         * @param req Instance of URLRequest
         */
        public function queue(loader:URLLoader, request:URLRequest):void
        {
            _queue.push({LOADER: loader, REQUEST: request});
            _next();
        }

        /**
         * Loads next loader in _queue
         */
        private function _next():void
        {
            if(_queue.length > 0)
            {
                var info:Object = _queue.pop();

                var loader:URLLoader = URLLoader(info.LOADER);

                loader.load(
                    URLRequest(info.REQUEST)
                );

                loader.addEventListener(Event.COMPLETE, _complete);
            }
        }

        /**
         * ..
         * Event.COMPLETE
         */
        private function _complete(e:Event):void
        {
            var loader:URLLoader = URLLoader(e.target);
            loader.removeEventListener(Event.COMPLETE, _complete);

            trace(loader.data);

            _next();
        }
    }
}

使用示例:

var list:Array = [
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php"
];

var lc:LoadQueuer = new LoadQueuer();

for each(var i:String in list)
{
    lc.queue(
        new URLLoader(),
        new URLRequest(i)
    );
}

希望这会对你有所帮助。

答案 1 :(得分:1)

发现这个:

  

浏览器通常只允许同时使用2个HTTP KeepAlive   连接。其他连接被推迟。


  

对于这种情况,最佳实践要求使用单个实例   的URLLoader;你有可能通过竞争在某个地方被封锁   调用。同样,您可以尝试使用简单的标志来检测是否   你的装载机在制作另一个之前忙于现有的通话;   这是一个使用单个加载器发出请求的工作示例   五秒钟,显示单个加载器和“isOpen”检查:

试试这个答案: URLLoader gets stuck when polling