«связать» ряд функций в ActionScript 3
-
06-07-2019 - |
Вопрос
Я вызываю функцию и добавляю прослушиватель, когда функция возвращает некоторые данные.когда данные возвращаются, мне нужно вызвать другую функцию и так далее.
Есть ли простой способ «связать» эти функции вместе, чтобы первая сработала - ждала прослушивателя, затем запускала вторую, создавая для этого прослушиватель, и так далее, пока последняя не вызовет отдельную функцию, которая определена в начале .Я полагаю, что он будет работать по тем же строкам, что и сценарии массовой загрузки.
Я предполагаю, что код будет работать примерно так:
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 содержит классы, которые довольно хорошо справляются с цепочками асинхронных операций.