2009-06-23 4 views
2

J'appelle une fonction et j'ajoute un écouteur lorsque la fonction retourne des données. Lorsque les données sont retournées, je dois appeler une autre fonction et ainsi de suite. Existe-t-il un moyen facile de 'chaîner' ces fonctions ensemble de sorte que le premier se déclenche - attend l'auditeur puis déclenche le second en créant un écouteur pour cela et ainsi de suite jusqu'à ce que le dernier appelle une fonction séparée qui est défini au départ. Je suppose que cela fonctionne sur les mêmes lignes que les scripts du chargeur en bloc.'enchaîner' une série de fonctions ensemble dans actionscript 3

Je le code de travail d'envisager quelque chose comme ceci:

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 
} 

Merci, Josh

+0

Avez-vous regardé BulkLoader? Il semble faire ce que vous cherchez: code.google.com/p/bulk-loader/. – quoo

Répondre

2

Je voudrais juste faire quelque chose de simple comme: (aussi, ce code est sorta psuedo, vous aurez besoin des événements d'erreur corrects et d'autres choses)

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

je pourrais être mal compris vos intentions, mais de ce que vous avez décrit, vous pouvez les enchaîner lorsque les gestionnaires sont appelés ... comme: Vouliez-vous faire quelque chose comme ça mais avec une syntaxe plus condensée?

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

oui je veux le faire mais condensé! lors du chargement d'un ou deux cela fonctionne très bien, mais j'ai des situations où j'ai besoin de charger différentes combinaisons de données et donc il devient salissant – Josh

0

Cette interface me semble bonne. L'implémentation dépend de la manière dont les fonctions renvoient leurs données. AS3 ne supporte pas les threads, vous devez donc écrire vos fonctions getData() pour les exécuter de manière asynchrone. Si vous chargez des données à partir d'un site distant ou quelque chose d'aussi simple, utilisez simplement les fonctions intégrées du chargeur, utilisez getBytesLoaded() pour savoir quand elles sont terminées et appelez votre rappel OnComplete lorsque tout le monde est chargé.

Si vous faites un calcul très long, vous allez devoir le décomposer. Quelque chose comme:

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

Sous quelque chose comme ça pour chaque type de calcul que vous devez faire, puis passer des cas dans votre chargeur de données. Ayez-leur Step() une fois par image, et appelez le rappel OnComplete quand ils sont tous terminés.

0

splinklibrary contient des classes qui traitent des opérations asyncronous chaînés tout à fait bien .

2

Été là, fait cela. Voici le code 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); 
      } 
     } 

    } 

} 

De toute évidence, vous voulez ajouter une fonction de gestionnaire d'erreurs, de garder trace de ce qui a échoué et réussi, ajouter des options pour fast-échec par rapport à tout faire-you-can, etc.

  • Paul
Questions connexes