AS3中的异步分块?

时间:2012-02-03 16:29:17

标签: flash

我找到了一些代码来分解流程密集型循环,以便仍然可以进行屏幕渲染。

我几乎让它工作 - 唯一的事情是我必须按下“开始”按钮才能完成整个过程,而不是自动完成 - 我不能正确理解'返回':< / p>

test_csv_btn.addEventListener(MouseEvent.CLICK, testCSVFunc);

function testCSVFunc ( event : Event ) {

    for (var i:uint = 0; i < csv.data.length; i++) {        

        if (csv.data[i][colArtist] == '') {         

            csv.data[i][colArtist] = csv.data[i-1][colArtist];

        }       
    }

    enterFrame();
}


//pseudo code
var allowedTime = 1000/24 - 2 - 2;
var startTime = 0;
var savedIndex = 0;


function enterFrame() {

    startTime = getTimer();

    var i, n = csv.data.length;
    for (i=savedIndex; i<n; i++){

        if (getTimer() - startTime > allowedTime){
            savedIndex = i;
            return;
        }
        trace(i);
        finalCSV(csv.data[i]);
    }

    //complete();
    trace ('done');
}


function finalCSV ( file ) {    

    if (file[colTitle] != '') {             

        trace(file[colTitle]);
        csvHolder.csvText.appendText(file[colArtist]+' -- '+file[colTitle]+'\n');
    }

}

就目前而言,enterFrame确实有效,直到达到计时器限制,然后停止。为了让它恢复,我必须按下test_csv_btn来迭代下一个块,依此类推,直到完成所有操作。

如何让流程自动继续直到完成?它似乎在每个块的末尾返回testCSVFunc并停止。

感谢您的帮助。

3 个答案:

答案 0 :(得分:0)

您正在使用的行为称为“伪线程”,您可以在Internet上找到许多通用实现。您可以在as3commons库中找到类似Java线程的文件,和/或查看this tutorial以了解基础知识。

答案 1 :(得分:0)

代码的作用(在高级别上)是这样的:

  1. 单击该按钮时,将设置输入数据(testCSVFunc() - 循环确保空的艺术家单元格填充前一行的艺术家单元格。

  2. 然后它(testCSVFunc())调用enterFrame()

  3. enterFrame()重复调用finalCSV,在文本字段中添加“艺术家 - 标题”行。

  4. ...直到指定时间过去。即1000 / 24 - 2 - 2 =约。 38毫秒 - 相当于每秒 24 帧的帧的持续时间略小。不知道为什么“ - 2 - 2”,但我的想法是让每一帧都花费一些时间让Flash做其他事情(比如渲染舞台)。

  5. 当38毫秒被用于处理时,它会停止(return语句) - 并且在你再次点击之前不再做任何事情(此时它将从{{1}调用) } - 继续它停止的地方 - 在testCSVFunc())。 savedIndex将继续处理数据,直到testCSVFunc不再为真 - 即,当CSV中没有剩余项目时。

  6. 我猜这个想法是testCSVFunc应该只被调用一次。它设置所有数据(调用它两次将相同的数据再次添加到“待办事项列表”)。然后,finalCSV应该处理该数据并将其添加到文本字段中。

    这意味着i < n不应该由testCSVFunc直接调用(由点击触发) - 它意味着每帧调用一次(因此名称),直到所有数据都被处理完毕

    即。而不是调用enterFrame(),而是将其设置为ENTER_FRAME事件处理程序:

    enterFrame()

    这样,点击时,“线程”将开始,每帧将执行addEventListener(Event.ENTER_FRAME, enterFrame);

    请记住在enterFrame()声明中添加event:Event参数 - 即使您不使用它。否则,您将收到有关缺少参数的错误:

    enterFrame()

    当完成处理时(当循环不再迭代时,因为function enterFrame(event:Event):void { ... } 不再为真),再次禁用事件处理程序是个好主意,即:

    i < n

    否则它将继续调用“工人方法”,即使它没有更多的工作要做。

    总而言之,这意味着每个帧,大部分帧时间(38毫秒)将用于填写文本字段,之后可以执行阶段的渲染。我可能会设置// done removeEventListener(Event.ENTER_FRAME, enterFrame); trace('done'); 略低于此。

    正如weltraumpirat所说,有一些通用的实现可能更有效并且可能会处理Flash的特性,但作为一个实验来研究“伪线程”实际上是如何工作的,这是一个很好的学习练习。

答案 2 :(得分:0)

你试过workers吗?它们允许在没有解决方法的情况下创建同时执行的线程。