Сбор и идентификация функций в массиве в ActionScript - PullRequest
2 голосов
/ 29 декабря 2011

Итак, я хочу сделать что-нибудь, где я собираю функции для последующего вызова при выполнении определенного условия. Э.Г.

function doSomething(someArg:Object):void {
    if (conditionIsFalse){
        operationsToDoWhenConditionIsTrue.push(function(){
           doSomething(someArg);
        });
    }
}

function onConditionBecomingTrue():void {
    while (operationsToDoWhenConditionIsTrue.length > 0){
        operationsToDoWhenConditionIsTrue.shift()();
    }    
}

Пока все хорошо. Однако в какой-то момент я хочу перебрать операции ToDoWhenConditionIsTrue и определить и заменить функцию. В псевдокоде внутри метода doSomething это будет:

function doSomething(someArg:Object):void {
   if (conditionIsFalse){
      for (var i:int = 0; i<operationsToDoWhenConditionIsTrue; i++){
         // pseudo code here
         if (typeof operationsToDoWhenConditionIsTrue[i] == doSomething){
             operationsToDoWhenConditionIsTrue[i] = doSomething(someArg);
         }
      }
   }
}

В основном, если doSomething вызывается дважды, я хочу, чтобы операции OperationsToDoWhenConditionIsTrue удерживали самый последний вызов. Очевидно, что вызовы заключены в function () {}, поэтому все функции одинаковы. Есть ли способ, которым я могу достичь того, чего я хочу?

1 Ответ

1 голос
/ 29 декабря 2011

Создайте функцию идентификатора, которая может идентифицировать операции, которые вы хотите обнаружить, как одинаковые.Присвойте идентификатор как свойство анонимной функции, которую вы добавляете в очередь.Когда вы перебираете очередь, записывайте идентификаторы в коллекцию.Не выполняйте операцию, если она уже находится в коллекции.

function doSomething(someArg:Object):void {
    if (conditionIsFalse){
        var operation = function(){
           doSomething(someArg);
        };
        operation.operationID = objID(...);
        operationsToDoWhenConditionIsTrue.push(operation);
    }
}

function onConditionBecomingTrue():void {
    var done = {}, f;
    while (operationsToDoWhenConditionIsTrue.length > 0){
        f = operationsToDoWhenConditionIsTrue.shift();
        if (! f.operationID in done) {
            done[f.operationID] = true;
            f()
        }
    }    
}

В качестве более эффективного варианта вы можете индексировать очередь по идентификаторам, чтобы функцию можно было добавить в очередь только один раз.Однако вы потеряете контроль над порядком выполнения операций.

var operationsToDoWhenConditionIsTrue:Object = {};

function doSomething(someArg:Object):void {
    if (conditionIsFalse){
        operation.operationID = ...;
        operationsToDoWhenConditionIsTrue[objID(...)] = function(){
           doSomething(someArg);
        };
    }
}

function onConditionBecomingTrue():void {
    for (id in operationsToDoWhenConditionIsTrue){
        operationsToDoWhenConditionIsTrue[id]();
    }
    operationsToDoWhenConditionIsTrue = {};
}

Если вам нужно сохранить последовательность (чтобы операции выполнялись в том порядке, в котором они были сначала добавлены в очередь, или в порядкеони были добавлены в последний раз), создайте тип очереди, который можно индексировать как по идентификатору, так и по последовательности, что можно сделать, сохранив сопоставления между типами индекса.Примечание: следующее не проверено.

class OperationQueue {
    protected var queue:Array = [];
    protected var idToSeq:Object = {};

    public function push(op:Function):void {
        /* Orders by last insertion. To order by first insertion,
           simply return if the operation is already in the queue.
         */
        if (op.id in this.idToSeq) {
            var seq = this.idToSeq[op.id];
            delete this.queue[seq];
        }
        this.queue.push(op);
        this.idToSeq[op.id] = this.queue.length-1;
    }
    public function runAll():void {
        var op;
        while (this.queue.length > 0) {
            if ((op = this.queue.shift())) {
                delete this.idToSeq[op.id];
                op();
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...