Pregunta

Llamo a una función y agrego un oyente para cuando la función devuelve algunos datos. cuando se devuelven los datos, necesito llamar a otra función, etc.

¿Hay una manera fácil de 'encadenar' estas funciones para que la primera se active? Espera al oyente y luego activa la segunda creando un oyente para eso y así sucesivamente hasta que la última llame a una función separada que se define al principio. Supongo que trabajaría en las mismas líneas que las secuencias de comandos del cargador masivo.

Estoy pensando que el código funcione de esta manera:

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
}

Gracias Josh

¿Fue útil?

Solución

Simplemente haría algo simple como: (además, este es un seudocódigo de clasificación, necesitará los eventos de error correctos y esas cosas)

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

Otros consejos

He estado allí, hecho eso. Aquí está el código 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);
            }
        }

    }

}

Obviamente, querrá agregar una función de controlador de errores, realizar un seguimiento de cuáles fallaron y tuvieron éxito, agregar opciones para fallas rápidas versus hacer todo lo que pueda, etc.

  • Paul

Podría estar malinterpretando sus intenciones, pero por lo que describió, puede encadenarlas cuando se llaman los controladores ... como: ¿Quería hacer algo como esto pero con una sintaxis más condensada?

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...
}

Esa interfaz me parece buena. La implementación depende de cómo las funciones devuelven sus datos. AS3 no admite subprocesos, por lo que debe escribir sus funciones getData () para ejecutarlas de forma asincrónica. Si está cargando datos desde un sitio remoto o algo así, esto es fácil, solo use las funciones del cargador incorporado, use getBytesLoaded () para saber cuándo terminaron y llame a su devolución de llamada OnComplete cuando todos estén cargados.

Si solo estás haciendo un cálculo realmente largo, tendrás que dividirlo. Algo así como:

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

Subclasifique algo así para cada tipo de cálculo que necesite hacer, luego pase instancias a su cargador de datos. Haga que Step () una vez por cuadro y llame a la devolución de llamada OnComplete cuando hayan terminado.

splinklibrary contiene clases que se ocupan bastante bien de operaciones asincrónicas encadenadas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top