سؤال

أقوم باستدعاء وظيفة وإضافة مستمع عندما تقوم الوظيفة بإرجاع بعض البيانات.عندما يتم إرجاع البيانات أحتاج إلى استدعاء وظيفة أخرى وما إلى ذلك.

هل هناك طريقة سهلة "لربط" هذه الوظائف معًا بحيث يتم تشغيل الوظيفة الأولى - تنتظر المستمع ثم تقوم بتشغيل الثانية لإنشاء مستمع لذلك، وهكذا حتى يستدعي الأخير وظيفة منفصلة تم تحديدها في البداية .أفترض أن العمل على نفس الخطوط مثل البرامج النصية للتحميل المجمع.

أتصور أن الكود يعمل بشيء من هذا القبيل:

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

والفئة الفرعية شيء من هذا القبيل لكل نوع من حساب ما عليك القيام به، ثم تمرير الحالات إلى محمل البيانات الخاصة بك. يكون لهم الخطوة () مرة واحدة في الإطار، واستدعاء رد OnComplete عند الانتهاء فقط.

splinklibrary تحتوي على فئات التي تتعامل مع عمليات asyncronous بالسلاسل جيد للغاية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top