Вопрос

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

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

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

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() {/* ... */}
}

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top