Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flash AS3-URLLoader再次加载最后一个数据_Flash_Actionscript 3_Urlloader - Fatal编程技术网

Flash AS3-URLLoader再次加载最后一个数据

Flash AS3-URLLoader再次加载最后一个数据,flash,actionscript-3,urlloader,Flash,Actionscript 3,Urlloader,好的,这里有一个奇怪的错误 在我的应用程序中,我加载了多个xml文件。为了加载它们,我总是创建一个新的URLLoader。没什么特别的 第一个文件可以正常工作,第二个也可以。 然而,第三个文件报告说加载得很好,但它所保存的数据实际上是第二个文件的数据。 当前的解决方法是加载第三个文件两次,这在某种程度上是有效的。。。奇怪 我完全不知道这样的事情怎么会发生。 当然,这三个文件都是具有不同路径的不同文件 这里是相关的课程,希望有什么用,如果有什么不清楚的地方,请询问。 DownloadJob类只是一

好的,这里有一个奇怪的错误

在我的应用程序中,我加载了多个xml文件。为了加载它们,我总是创建一个新的URLLoader。没什么特别的

第一个文件可以正常工作,第二个也可以。 然而,第三个文件报告说加载得很好,但它所保存的数据实际上是第二个文件的数据。 当前的解决方法是加载第三个文件两次,这在某种程度上是有效的。。。奇怪

我完全不知道这样的事情怎么会发生。 当然,这三个文件都是具有不同路径的不同文件

这里是相关的课程,希望有什么用,如果有什么不清楚的地方,请询问。 DownloadJob类只是一个包含字符串和函数对象的助手类。下载完成后调用后一个

    // Actual class stuff
    private var _downloadQueue  :Array = new Array();

    /**
     * Adds a download to the queue. Will be started immediatly.
     * @param   p_url       The URL of the download.
     * @param   p_callback  The function to call when the download is finished. Has to take a DisplayObject/Sound/String as first parameter.
     */
    public function addDownload(p_url:String, p_callback:Function) :void
    {
        var job :DownloadJob = new DownloadJob(p_url, p_callback);
        _downloadQueue.push(job);

        debug.ttrace("added: " + job.url);

        // If it is the only item, start downloading
        if (_downloadQueue.length == 1)
        {
            var job :DownloadJob = DownloadJob(_downloadQueue[0]);
            load(job);
        }
    }

    /**
     * Will call the callback and dispatch an event if all loading is done.
     * @param   p_event The event that is passed when a download was completed.
     */
    private function downloadComplete(p_event:Event) :void 
    {
        var job :DownloadJob = DownloadJob(_downloadQueue[0]);
        var downloaded :Object = p_event.target;
        _downloadQueue.splice(0, 1);

        debug.ttrace("completed: " + job.url);

        // Notify via callback
        if (downloaded is LoaderInfo)
        {
            job.callback(downloaded.content);
        }
        else if (downloaded is Sound)
        {
            job.callback(downloaded);
        }
        else if (downloaded is URLLoader)
        {
            // This one holds the data of the previously loaded xml, somehow
            job.callback(URLLoader(downloaded).data);
        }

        // Continue downloading if anything is left in the queue
        if (_downloadQueue.length > 0)
        {
            var job :DownloadJob = DownloadJob(_downloadQueue[0]);
            load(job);
        }
        else
        {
            dispatchEvent(new Event(EVENT_DOWNLOADS_FINISHED));
        }
    }

    /**
     * Will load the passed job immediatly.
     * @param   p_job   The job to load.
     */
    private function load(p_job:DownloadJob) :void
    {
        // Different loaders needed for data, sound and non-sound
        if (p_job.url.indexOf(".xml") != -1 ||
            p_job.url.indexOf(".txt") != -1)
        {
            var urlloader :URLLoader = new URLLoader();
            urlloader.addEventListener(Event.COMPLETE, downloadComplete);
            urlloader.addEventListener(IOErrorEvent.IO_ERROR, handleError);
            urlloader.load(new URLRequest(p_job.url));
        }
        else if (   p_job.url.indexOf(".mp3") != -1 &&
                    p_job.url.indexOf(".flv") != -1)
        {
            var sound :Sound = new Sound();
            sound.addEventListener(Event.COMPLETE, downloadComplete);
            sound.addEventListener(IOErrorEvent.IO_ERROR, handleError);
            sound.load(new URLRequest(p_job.url));
        }
        else
        {
            var loader :Loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, downloadComplete);
            loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, handleError);
            loader.load(new URLRequest(p_job.url));
        }
    }

}

我花了一些时间在你的课堂上,没有发现任何错误,即使是从计时器发出随机的
addDownload
命令,一切都按预期进行,没有混乱,没有奇怪的数据残留。我只能猜测这个问题可能与ActionScript中奇怪的变量处理有关,如果它真的在您发布的代码中的话

于是我冒昧地重新安排了一下你们的课程:

  • 我将队列的类型更改为
    Vector.
    。这让我们摆脱了所有的类型铸造
  • 当前下载存储在字段变量
    currentJob
    中。无论如何,一次只能做一份工作。这消除了所有函数参数
  • 只有当
    currentJob
    不是
    null
    时,作业才会添加到队列中,即下载实际上正在进行中。如果不需要等待,我们不必排队。这只剩下对每个
    push()
    splice()
    的一个调用。关于什么时候添加和删除内容,没有更多的不确定性
  • 删除了匈牙利符号(我们在ActionScript中不这么做)
  • 将较大的方法拆分为更小、更可读的块(帮助我思考:)
  • 删除了除API方法之外的所有注释(我相信代码本身就是最好的)
尝试将下面的代码与上一个类交换,看看问题是否仍然存在。如果是这样的话,我很确定问题存在于加载程序之外,可能存在于处理负载的回调函数中

private static const EVENT_DOWNLOADS_FINISHED : String = "EVENT_DOWNLOADS_FINISHED";
private var currentJob : DownloadJob;
private var downloadQueue : Vector.<DownloadJob> = new Vector.<DownloadJob> ();

/**
 * Adds a download to the queue. Will be started immediatly.
 * @param   url       The URL of the download.
 * @param   callback  The function to call when the download is finished. Has to take a DisplayObject/Sound/String as first parameter.
 */
 public function addDownload ( url : String, callback : Function ) : void {
    var job : DownloadJob = new DownloadJob ( url, callback );
    if (currentJob) downloadQueue.push ( job );
    else {
        currentJob = job;
        load ();
    }
}

private function load () : void {
    if ( jobIsText () ) loadText ();
    else if ( jobIsSound () ) loadSound ();
}

private function jobIsText () : Boolean {
    var url : String = currentJob.url;
    return url.indexOf ( ".xml" ) != -1 || url.indexOf ( ".txt" ) != -1;
}

private function jobIsSound () : Boolean {
    var url : String = currentJob.url;
    return url.indexOf ( ".mp3" ) != -1;
}

private function loadText () : void {
    var urlloader : URLLoader = new URLLoader ();
    urlloader.addEventListener ( Event.COMPLETE, handleComplete );
    urlloader.addEventListener ( IOErrorEvent.IO_ERROR, handleError );
    urlloader.load ( new URLRequest ( currentJob.url ) );
}

private function loadSound () : void {
    var sound : Sound = new Sound ();
    sound.addEventListener ( Event.COMPLETE, handleComplete );
    sound.addEventListener ( IOErrorEvent.IO_ERROR, handleError );
    sound.load ( new URLRequest ( currentJob.url ) );
}

private function handleComplete ( ev : Event ) : void {
    processPayload ( ev.target );

    if (downloadQueue.length > 0) loadNext ();
    else dispatchEvent ( new Event ( EVENT_DOWNLOADS_FINISHED ) );
}

private function handleError ( ev : Event ) : void {
    trace ( "Error while downloading:" + currentJob.url );
}

private function processPayload ( loader : Object ) : void {
    currentJob.callback ( getPayload ( loader ) );
    currentJob = null;
}

private function loadNext () : void {
    currentJob = downloadQueue.splice ( 0, 1 )[0];
    load ();
}

private function getPayload ( loader : Object ) : Object {
    return (loader is LoaderInfo) ? loader.content :     
               (loader is URLLoader) ? URLLoader ( loader ).data :
                   loader;
}
private static const EVENT\u DOWNLOADS\u FINISHED:String=“EVENT\u DOWNLOADS\u FINISHED”;
私有var currentJob:DownloadJob;
私有var下载队列:Vector.=新载体。();
/**
*将下载添加到队列中。将立即启动。
*@param url下载的url。
*@param callback下载完成时要调用的函数。必须将DisplayObject/Sound/String作为第一个参数。
*/
公共函数addDownload(url:String,callback:function):void{
var job:DownloadJob=新的DownloadJob(url,回调);
if(currentJob)downloadQueue.push(作业);
否则{
currentJob=job;
荷载();
}
}
私有函数加载():void{
if(jobIsText())loadText();
else if(jobIsSound())loadSound();
}
私有函数jobIsText():Boolean{
var url:String=currentJob.url;
返回url.indexOf(“.xml”)!=-1 | | url.indexOf(“.txt”)!=-1;
}
私有函数jobIsSound():Boolean{
var url:String=currentJob.url;
返回url.indexOf(“.mp3”)!=-1;
}
私有函数loadText():void{
var urlloader:urlloader=新的urlloader();
urlloader.addEventListener(Event.COMPLETE、handleComplete);
urlloader.addEventListener(IOErrorEvent.IO_ERROR,handleError);
urlloader.load(新的URLRequest(currentJob.url));
}
私有函数loadSound():void{
变量声音:声音=新声音();
sound.addEventListener(事件完成,handleComplete);
sound.addEventListener(IOErrorEvent.IO_ERROR,handleError);
sound.load(新的url请求(currentJob.url));
}
私人功能handleComplete(ev:事件):无效{
过程有效载荷(ev.target);
如果(downloadQueue.length>0)loadNext();
else dispatchEvent(新事件(事件下载完成));
}
私有函数句柄错误(ev:事件):无效{
跟踪(“下载时出错:“+currentJob.url”);
}
私有函数processPayload(加载程序:对象):void{
currentJob.callback(getPayload(loader));
currentJob=null;
}
私有函数loadNext():void{
currentJob=downloadQueue.splice(0,1)[0];
荷载();
}
私有函数getPayload(加载程序:对象):对象{
返回(loader是LoaderInfo)?loader.content:
(加载器是URLLoader)?URLLoader(加载器)。数据:
装载机;
}

好的,我发现如果每次都不使用新的URLLoader,它就可以工作。当我对所有请求使用相同的URLLoader时,错误就消失了。这是一个我可以接受的解决办法。。。不过,这个错误使我困惑。一定是Flash中的某种内存错误。首先,你要检查文件是FLV还是MP3是错误的。你的条件句是说&¬ | |。第二,我不太确定你能不能把FLV加载到声音类中,但我可能错了。第三,你能发布所有的代码吗?因为这段代码只显示了你是如何加载的,而真正的问题很可能来自你传递给addDownload的URL生成。感谢声音提示,我发现声音在不久前只能加载mp3,但忘了将其从类中删除。正如我上面的评论所示,URL生成是正确的。DownloadJob类在哪里?肯定是出了什么问题。创建多个URLloader不应导致该问题。我写过这样的加载程序,甚至将它们部署到拥有数千万用户的大型网站上。。。我从未经历过这样的错误。如果它起作用,而你是h