'连锁'一系列功能在动作脚本3中

时间:2009-06-23 15:29:43

标签: flash actionscript-3 event-handling listeners

我正在调用一个函数并在函数返回某些数据时添加一个监听器。当返回数据时,我需要调用另一个函数,依此类推。

是否有一种简单的方法可以将这些函数“链接”起来,以便第一个函数触发 - 等待侦听器然后触发第二个触发器创建一个侦听器,依此类推,直到最后一个调用一个单独的函数定义在开始时。我认为它与批量加载器脚本的工作方式相同。

我正在设想这样的代码:

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 个答案:

答案 0 :(得分:2)

我会做一些简单的事情:(另外,这是排序伪代码,你需要正确的错误事件和东西)

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

答案 1 :(得分:2)

去过那里,做到了。这是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 :(得分:0)

我可能会误解你的意图,但是从你所描述的内容来看,你可以在调用处理程序时将它们链接起来......就像:你想做这样的事情但是有更复杂的语法吗?

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

答案 3 :(得分:0)

该界面对我来说很好看。实现取决于函数如何返回其数据。 AS3不支持线程,因此您必须编写getData()函数以异步运行。如果您正在从远程站点加载数据或者这很容易,只需使用内置的加载器函数,使用getBytesLoaded()来告知它们何时完成,并在每个人加载时调用OnComplete回调。

如果你只是做了很长时间的计算,那么你将不得不将其分解。类似的东西:

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

为您需要执行的每种计算子类化类似的东西,然后将实例传递到数据加载器中。每帧都有一次Step(),并在完成后调用OnComplete回调。

答案 4 :(得分:0)

splinklibrary包含很好地处理链式异步操作的类。