在actionscript中收集和识别数组中的函数

时间:2011-12-28 22:56:50

标签: actionscript-3 function

所以,我想做一些事情,我收集函数,以便在满足某个条件时调用。 E.g。

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

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

到目前为止一切顺利。但是在某些时候我想迭代operationsToDoWhenConditionIsTrue并识别和替换一个函数。在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 个答案:

答案 0 :(得分:1)

创建一个标识符函数,可以将要检测的操作标识为相同。将ID指定为您添加到队列的匿名函数的属性。迭代队列时,记录集合中的ID。如果它已经在集合中,请不要执行该操作。

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()
        }
    }    
}

作为一种更有效的变体,您可以按ID索引队列,这样一个函数只能添加一次到队列中。但是,您将无法控制执行操作的顺序。

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 = {};
}

如果您需要保留序列(以便按照它们首次添加到队列中的顺序执行操作,或按照上次添加的顺序执行),请创建一个可由ID和序列索引的队列类型,您可以通过在索引类型之间存储映射来执行此操作。注意:以下是未经测试的。

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();
            }
        }
    }
}