0

我想上传带有多个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();
        }
    }

加载操作是异步和单线程的。为什么会被阻塞?

4

2 回答 2

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

希望这对您有所帮助。

于 2011-09-19T03:57:22.627 回答
1

发现这个:

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


对于这种情况,最佳实践要求使用 URLLoader 的单个实例;很有可能你在某个地方被竞争电话阻止了。同样,您可以尝试使用一个简单的标志来检测您的加载程序是否在进行另一个呼叫之前忙于现有呼叫;这是一个使用单个加载器每五秒发出一次请求的工作示例,显示了单个加载器和“isOpen”检查:

试试这个答案: URLLoader 在轮询时卡住

于 2011-09-19T07:48:28.300 回答