0

リモートサーバーから取得してローカルに保存するために、ファイル名の小さな配列をループしています。このビットは正常に動作します。

問題は、ダウンロードが完了したときに次の関数を実行する必要があることです。

現在、私の関数は step2() と呼び、すべての FileStreams が終了する前に呼び出されます (実際、その関数が開始される前に呼び出されます!)

openAsynch を使用する場合、完全なイベント リスナーがあることを読みましたが、すべてのファイル (たとえば 3 つのリモート swfs) が書き込まれていることを確認してから、step2() 関数を開始する必要があります。

これについてどうすればよいですか?

以下のコード:

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

3 に答える 3

0

step2(); だけ動かせませんか?fileCompleteHandler 関数の最後に? この時点で step2(); for(i = 0; i < myArray.length; i++) ループを通過した直後に呼び出されます (これは早い方法です)。

于 2013-01-07T16:56:51.213 に答える
0

あなたの問題は、for loop非同期モデルでは決して機能しません。そのため、再帰関数を使用する必要があります。

すべてのダウンロードが完了したときに呼び出される関数である downloadAllFiles メソッドの 2 番目の引数。その後、step2() などを呼び出すことができます。

IOErrorEvent などのファイルのダウンロード中に問題が発生したかどうかを確認してください...

    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);
    }
于 2013-01-08T05:33:32.043 に答える
0

What you are missing is a way to check that all files from your list are loaded, 3vliguy is right and your step2(); should be in the complete handler but, not alone, you have to also test if ALL files are loaded. you can do it in various ways, e.g. use file counter and when it is 0 (all files loaded) you will execute step2() else you will ignore it and just decrease counter.

p.s. the Raja Jaganathan way will work as well, only it is queued loading whereas with the counter you can start loading of all files at the beginning.

于 2013-01-08T08:19:56.167 に答える