«связать» ряд функций вместе в ActionScript 3 - PullRequest
2 голосов
/ 23 июня 2009

Я вызываю функцию и добавляю прослушиватель, когда функция возвращает некоторые данные. когда данные возвращаются, мне нужно вызвать другую функцию и т. д.

Существует ли простой способ «связать» эти функции вместе, чтобы первая запускалась - ждет слушателя, затем запускает второй, создавая слушателя для этого и так далее, пока последняя не вызовет отдельную функцию, которая определена в начале. Я бы предположил, что работает на тех же строках, что и скрипты массового загрузчика.

Я предполагаю, что код работает примерно так:

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
}

Спасибо, Джош

Ответы [ 5 ]

2 голосов
/ 26 июня 2009

Был там, сделал это. Вот код 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);
            }
        }

    }

}

Очевидно, что вы захотите добавить функцию обработчика ошибок, отслеживать, какие из них были неудачными и успешными, добавлять опции для быстрого отказа или все, что вы можете, и т. Д.

  • Пол
2 голосов
/ 23 июня 2009

Я бы просто сделал что-то простое, например: (также это код сорта псевдо, вам понадобятся правильные события ошибок и прочее)

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]; 
     }
}
0 голосов
/ 25 июня 2009

splinklibrary содержит классы, которые прекрасно справляются с асинхронными операциями в цепочке.

0 голосов
/ 23 июня 2009

Этот интерфейс выглядит хорошо для меня. Реализация зависит от того, как функции возвращают свои данные. AS3 не поддерживает потоки, поэтому вы должны написать свои функции getData () для асинхронного запуска. Если вы загружаете данные с удаленного сайта или что-то еще, это просто, просто используйте встроенные функции загрузчика, используйте getBytesLoaded (), чтобы сказать, когда они сделаны, и вызовите свой обратный вызов OnComplete, когда все загружены.

Если вы просто делаете очень длинные вычисления, вам придется их разбить. Что-то вроде:

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

Подкласс чего-то подобного для каждого вида вычислений, который вам нужно сделать, а затем передать экземпляры в ваш загрузчик данных. Сделайте так, чтобы они выполняли Step () один раз за кадр, и вызывайте обратный вызов OnComplete, когда все они будут завершены.

0 голосов
/ 23 июня 2009

Возможно, я неправильно понимаю ваши намерения, но из того, что вы описали, вы можете связать их при вызове обработчиков ... как: Вы хотели сделать что-то подобное, но с более сжатым синтаксисом?

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