質問

関数を呼び出して、関数がデータを返すときにリスナーを追加しています。データが返されたら、別の関数などを呼び出す必要があります。

最初の関数が起動するようにこれらの関数を「チェーン」する簡単な方法があります-リスナーを待ってから、2番目の関数を起動してそのリスナーを作成し、最後の関数が定義された別の関数を呼び出すまで開始時。バルクローダースクリプトと同じ行で作業すると思います。

このようなコードの動作を想定しています:

var dataLoader:DataLoader = new DataLoader(onAllComplete, onError);

dataLoader.add(getData1, {args1, args2}, listnerType.DATA_LOADED);
dataLoader.add(getData2, {args3, args4}, listnerType.DATA_LOADED);
dataLoader.add(getData3, {args5, args6}, listnerType.DATA_LOADED);

dataLoader.start();

private function onAllComplete(e:Array):void {
  //where e contains an array of all the event results
}
private function onError(e:Event):void {
  //will fire if there are any errors along the way
}

ありがとう、 ジョシュ

役に立ちましたか?

解決

次のような単純なことをするだけです(また、これはソート擬似コードです。正しいエラーイベントなどが必要です)

var numLoaded:int = 0;
var numError:int = 0;
var loadingIndex:int = 0;

var itemsToLoad:Array = ['img1.jpg', 'img2.jpg', 'img3.jpg'];

public function startLoading():void{
     loader.load(itemsToLoad[loadingIndex];
     loader.addEventListener(Event.COMPLETE, completeHandler);
}

public function completeHandler(event:Event):void{
     loadingIndex++;
     numLoaded++;
     if(numLoaded + numError >= itemsToLoad.length){
          onAllItemsComplete();
     }else{
          loader.load(itemsToLoad[loadingIndex];
     }
}

public function errorHandler(event:Event):void{
     loadingIndex++;
     numError++;
     if(numLoaded + numError >= itemsToLoad.length){
          onAllItemsComplete();
     }else{
        loader.load(itemsToLoad[loadingIndex]; 
     }
}

他のヒント

そこに行って、やった。 AS3コードは次のとおりです。

package com.vpg.rns.util {

    public class AsynchIterator {
        private var iteratorPosition:int;
        private var iterableObjects:Array;
        private var onApply:Function;
        private var onComplete:Function;
        private var done:Boolean;

        public function get position() { return iteratorPosition; }

        public function get isDone() { return done; }

        public function get size() { return iterableObjects.length; }

        /** Create an iterator that will call the given function repeatCall once for each object in iterableObjects, before finally calling completeCall once at the end.
         * The calls will be made asynchronously, with event handlers used to stitch it all together.
         *
         * @param iterableObjects ....... Every object in this array will be passed as the first argument to repeatCall, in order.
         * @param repeatCall ............ This function will be called once for each object in iterableObjects. Its signature is repeatCall(Object, Function).
         * @param completeCall .......... Called once after every item in the array has been processed.
         *
         *
         */
        public function AsynchIterator(iterableObjects:Array, repeatCall:Function, completeCall:Function) {
            this.iteratorPosition = 0; 
            this.iterableObjects = iterableObjects;
            this.onApply = repeatCall;
            this.onComplete = completeCall;
            this.done = false;
        }

        public function iterate():void {
            doNext();
        }

        private function doNext() {
            if (isDone) {
                // Do nothing - already called onComplete. 
            }
            else if (position == size) { 
                done = true;
                onComplete();
            }
            else {
                var obj:Object = iterableObjects[iteratorPosition++];
                onApply(obj, doNext);
            }
        }

    }

}

明らかに、エラーハンドラー関数を追加し、失敗したものと成功したものを追跡し、ファストフェイルとすべてを自由に実行するためのオプションを追加したいなどです。

  • ポール

私はあなたの意図を誤解しているかもしれませんが、あなたが説明したことから、ハンドラーが呼び出されたときにそれらを連鎖させることができます...

private function onComplete1(event:Event):void
{
    dataLoader.removeEventListener("onComplete", onComplete1);
    dataLoader.addEventListener("onComplete", onComplete2);

    ... // process event

    dataLoader.load(); // I don't remember the exact calls...
}

private function onComplete2(event:Event)void
{
    dataLoader.removeEventListener("onComplete", onComplete1);
    dataLoader.addEventListener("onComplete", onComplete2);

    ... // process event

    dataLoader.load(); // I don't remember the exact calls...
}

このインターフェースは私には良さそうです。実装は、関数がデータを返す方法に依存します。 AS3はスレッドをサポートしないため、getData()関数を作成して非同期で実行する必要があります。リモートサイトなどから簡単にデータをロードする場合は、組み込みのローダー関数を使用し、getBytesLoaded()を使用して完了を通知し、全員がロードされたらOnCompleteコールバックを呼び出します。

本当に長い計算をしているだけなら、分割する必要があります。次のようなもの:

class Computation {
    function Step() {/* ... */}
    function IsFinished() {/* ... */}
    function GetResult() {/* ... */}
}

必要な計算の種類ごとにそのようなサブクラスを作成し、インスタンスをデータローダーに渡します。フレームごとに1回Step()を実行し、すべて完了したらOnCompleteコールバックを呼び出します。

splinklibrary には、チェーン非同期操作を非常にうまく処理するクラスが含まれています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top