开发者

dealing with sequence of functions linearly (as3)

I want to have a series of functions that execute one after another instead of one within another.

here's what I mean...

Lets say you have three functions

f1(){
    trace("f1 start")
    f2();
    trace("f1 end")
}
f2(){
    trace("f2 start")
    f3();
    trace("f开发者_开发技巧2 end")
}
f3(){
    trace("f3 start")
    trace("f3 end")
}

if you run f1() you should get

f1 start
f2 start
f3 start
f3 end
f2 end
f1 end

Any ideas for mechanisms to push functions in a fifo order so that I can have:

f1 start
f1 end
f2 start
f2 end
f3 start
f3 end

If I use an function-execution function, how can I notify that the event has finished? Would every function need to have an event dispatcher for the functions to run asynchronously?


If the events run synchronously you can have something as simple as:

var fArray:Array = [f1, f2, f3];

fArray.forEach(function(item:Function, i:int, a:Array):void { 
    item();
});

The above will work if the functions are synchronous. As the execution order is guranteed.

On the other hand, if your functions may be asynchronous then you would need to use either events, signals, or callbacks.

I would probably use callbacks for this. See the example below. It's a shame you can't extend the Function class, but it has been marked as final. Anyway, in the example, the fManager gets called once at the start to get it going and does the rest automatically. Each time a function is done it calls the fManager with a reference to itself, so it can be removed from the list.

var fArray:Array = [f1, f2, f3];

function fManager(_f:Function = null) {
    // Remove the one that just finished
    if(_f !== null) {
        fArray.splice(_f, 1);
    }

    // Run the next one
    if(fArray.length > 0) {
        // sends in function manager
        fArray[0](arguments.callee);
    }
}

function f1(f:Function):void {
    trace("f1");

    // Captures the current function
    fManager(arguments.callee);
    return;
}

function f2(f:Function):void {
    trace("f1");

    // Captures the current function
    fManager(arguments.callee);
    return;
}

function f3(f:Function):void {
    trace("f3");

    // Captures the current function
    fManager(arguments.callee);
    return;
}

// Start the code
fManager();


played around with it a bit... now instead of the function running within other functions, it happens only within the execute function, the other functions (f1,f2 etc) close completely, because we're using the return function.

The advantage of running the function in this way is that any resources that the functions are using can not be edited by the same function, and in the case of resources that were created for the function, they can be marked for garbage collection before the next function starts.

public function startSequence():void {
    execute(f1);
}

public function execute($f1:Function):void {
    var $f2:Function = $f1();
    if ($f2 != null) {
        execute($f2);
    }
}

public function f1():Function {
    trace("f1");
    return f2
}


public function f2():Function {
    trace("f2");
    return null
}

Another way of doing this is using a timer event, where the event execution is taken care of by an onComplete listener with the time set to 0.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜