Search code examples
actionscript-3flashair

AS3 multiple file download, check when completed?


I am looping through a small array of file names to grab from a remote server and save locally. This bit works OK.

The problem is, I need to run my next function when the downloads are complete.

Currently, my function, lets call it step2(), gets called before all the FileStreams can finish (infact, its called before that function even starts!)

I read that there is a complete event listener when using openAsynch, but I need to check that all files, e.g. 3 remote swfs) have been written and then start step2() function.

How can I go about this?

Code below:

function onPlaylistComplete(e:Event)
{
    var myArray:Array = new Array();
    for each(var i in list_of_files)
    {
        myArray.push(i);
    }

    for(i = 0; i < myArray.length; i++)
    {
        swfItem = myArray[i];
        var urlString:String =  site_url + myArray[i];
        var urlReq:URLRequest = new URLRequest(urlString);
        var urlStream:URLStream = new URLStream();

        urlStream.addEventListener(Event.COMPLETE, urlStreamComplete(swfItem));
        urlStream.load(urlReq);
    }

    function urlStreamComplete(swfItem):Function
    {
        var downloadSwf:Function = function (event:Event):void {
            var fileData:ByteArray = new ByteArray();
            var stream = event.target;
            stream.readBytes(fileData, 0, stream.bytesAvailable);
            try {
                var f : File = File.documentsDirectory.resolvePath(swfItem);
                var fs : FileStream = new FileStream();
                fs.addEventListener(Event.COMPLETE, fileCompleteHandler);
                fs.openAsync(f, FileMode.WRITE);
                fs.writeBytes(fileData);
            }
            catch (err : Error) {
                trace(err.message);
            }
        }
        return downloadSwf;
    }

    function fileCompleteHandler(e:Event):void {
        e.target.close();
    }

    step2(); // this seems to run before UrlStreamComplete()
}

Solution

  • Problem with your for loop it will never work with Async model. so better need work to with recursive function.

    downloadAllFiles method second arg that is function called when all download are completed.Then you can call step2() or whatever may be.

    Make sure if any problem while download file like IOErrorEvent,etc...

        downloadAllFiles(myArray,function():void
        {
            step2();
        });
    
        function downloadAllFiles(myArray:Array, complete:Function):void
        {
            if(myArray && myArray.length == 0)
            {
                if(complete)
                    complete.call();
                return;
            }
    
            swfItem = myArray.shift();
    
            var urlString:String =  site_url + swfItem;
            var urlReq:URLRequest = new URLRequest(urlString);
            var urlStream:URLStream = new URLStream();
    
            urlStream.addEventListener(Event.COMPLETE, function (event:Event):void 
            {
                var fileData:ByteArray = new ByteArray();
                var stream = event.target;
                stream.readBytes(fileData, 0, stream.bytesAvailable);
    
                try {
                    var f : File = File.documentsDirectory.resolvePath(swfItem);
                    var fs : FileStream = new FileStream();
    
                    fs.addEventListener(Event.CLOSE, function(closeEvent:Event):void
                    {
                        downloadAllFiles(myArray,complete);
                        return;
                    });
                    fs.openAsync(f, FileMode.WRITE);
                    fs.writeBytes(fileData);
                }
                catch (err : Error) 
                {
                    trace(err.message);
                }
            });
    
            urlStream.load(urlReq);
        }