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

Actionscript 3 在actionscript中收集和识别数组中的函数,actionscript-3,function,Actionscript 3,Function,因此,我想做一些事情,收集函数,以便在满足特定条件后调用。例如 function doSomething(someArg:Object):void { if (conditionIsFalse){ operationsToDoWhenConditionIsTrue.push(function(){ doSomething(someArg); }); } } function onConditionBecomingTrue()

因此,我想做一些事情,收集函数,以便在满足特定条件后调用。例如

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

function onConditionBecomingTrue():void {
    while (operationsToDoWhenConditionIsTrue.length > 0){
        operationsToDoWhenConditionIsTrue.shift()();
    }    
}
到目前为止还不错。但是,在某个时刻,我希望迭代操作以确定条件是否正确,并标识和替换函数。在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(someArg:Object):void{
if(conditionIsFalse){

对于(var i:int=0;i创建一个标识符函数,该函数可以将要检测的操作标识为相同的操作。将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();
            }
        }
    }
}

识别相同操作的标准是什么?是否使用不同的
doSomething
功能识别操作(即每个功能之间的1-1映射)是的,我现在意识到,如果只删除typeof,我的伪代码就有点接近了。多亏了它的一个变体。我最终使用了一个数组,函数作为索引,参数作为值。然后,当调用时,我使用func.apply(这个,args)。这消除了对operationID的需要。请注意,对象属性必须是整数或字符串;使用函数意味着首先将其转换为字符串。这应该仍然有效,因为两个不同的函数不太可能具有相同的形式参数和主体。另一种方法是使用,它可以将对象作为键。