ActionScript 3不应该是一种简单的同步架构语言吗?

时间:2012-02-04 18:46:06

标签: actionscript-3 asynchronous trace synchronous

应该跟踪的一段简单代码:

  • RIEN
  • 测试
  • 完成!

我得到了一些远离它的东西,

情景A:

var __functions_to_execute:Array;

function start():void {
    __functions_to_execute  =[];

    __functions_to_execute.push(futile_trace());
    __functions_to_execute.push(futile_trace('test'));

    execute_functions();
}

function execute_functions():void {
    if(__functions_to_execute.length){
        //where shift on this Array remove the first element and returns it
        var exec:Function =__functions_to_execute.shift();
        exec;

        //I tried this too, just in case
        //__functions_to_execute[0];
        //__functions_to_execute.shift();
    } else  trace("done!");
}

function futile_trace(_value:String ='rien'):void {
    trace(_value);
    execute_functions();
}

start();
很简单。但结果是:

  • RIEN
  • 完成!
  • 测试

让我们添加一个已弃用的函数,然后将futile_trace函数更改为:

function futile_trace(_value:String ='rien'):void {
    trace(_value);
    setTimeout(execute_functions, 0);
}

然后结果是:

  • RIEN
  • 测试
  • 完成!

好的,我告诉自己,为什么不,让我在调用execute_functions时改变范围,所以我试过了:

function futile_trace(_value:String ='rien'):void {
    trace(_value);
    extra_step();
}

function extra_step():void {
    execute_functions();
}
猜猜结果是什么?!是的:

  • RIEN
  • 完成!
  • 测试

所以?追踪功能是不是很糟糕?那慢吗?事实上,将一个参数传递给函数需要花费那么多时间来比较另一个吗?我的意思是......哇!

我能做些什么来避免这种奇怪的现象?

(为了记录,我的项目不是追踪{rien,done和test} ...我有15k行代码,如果我用“忽略跟踪语句”编译它们会有完全不同的反应。

感谢您的投入。

2 个答案:

答案 0 :(得分:3)

您正在执行这些函数并将其返回值添加到__functions_to_execute数组,而不是函数本身。

您的函数execute_functions实际上没有做任何事情。我试图在线解释序列:

function start():void {
    __functions_to_execute  =[];
    // 1. traces 'rien' first because futile_trace() is called with no args
    // 2. 'done!' will be traced inside execute_functions because the array is still empty
    // 3.undefined will be pushed into the array next
    __functions_to_execute.push(futile_trace());
    // 4. traces 'test'
    // execute_functions does not trace anything because __functions_to_execute is non-empty
    // but it also doesn't do anything because it is just removing the `undefined` value from the start of the array.
    __functions_to_execute.push(futile_trace('test'));

    execute_functions();
}

更像这样的事情应该表达你的期望。它存储在数组函数引用中,以及调用函数时应传递的参数。

var __functions_to_execute:Array;

function start():void {
    __functions_to_execute = [];

    __functions_to_execute.push({func:futile_trace, args:[]});
    __functions_to_execute.push({func:futile_trace, args:['test']});

    execute_functions();
}

function execute_functions():void {
    if(__functions_to_execute.length){
        var obj:Object = __functions_to_execute.shift();
        obj.func.apply(null, obj.args);
    } else  trace("done!");
}

function futile_trace(_value:String ='rien'):void {
    trace(_value);
    execute_functions();
}

start();

答案 1 :(得分:0)

对于方案A,你实际上并没有将futile_trace推送到数组 - 你正在调用它(注意函数名后面的()),然后推送结果对该数组的调用。

换句话说:

  1. 您致电futile_trace()
  2. futile_trace跟踪'rien',因为您没有传递任何价值。
  3. futile_trace来电_execute_functions
  4. 此时尚未推送任何内容,因此_execute_functions跟踪'已完成!'
  5. _execute_functions返回。
  6. _futile_trace返回。
  7. 推送futile_trace()(void)的结果。
  8. 您致电futile_trace('test')
  9. futile_trace()输出'test'
  10. futile_trace来电_execute_functions
  11. _execute_functions从数组中移出void
  12. _execute_functions执行void;(无效)
  13. 等。等
  14. 如果您需要将函数传递给另一个函数或在变量中存储对它的引用,请确保您没有调用它。

    __functions_to_execute.push(futile_trace);
    // Use an anonymous function to pass with arguments without executing:
    __functions_to_execute.push(function() { futile_trace('test'); });
    

    ...并在_execute_functions 记住这些问题:

    exec();