我找到了一些代码来分解流程密集型循环,以便仍然可以进行屏幕渲染。
我几乎让它工作 - 唯一的事情是我必须按下“开始”按钮才能完成整个过程,而不是自动完成 - 我不能正确理解'返回':< / 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并停止。
感谢您的帮助。
答案 0 :(得分:0)
您正在使用的行为称为“伪线程”,您可以在Internet上找到许多通用实现。您可以在as3commons库中找到类似Java线程的文件,和/或查看this tutorial以了解基础知识。
答案 1 :(得分:0)
代码的作用(在高级别上)是这样的:
单击该按钮时,将设置输入数据(testCSVFunc()
- 循环确保空的艺术家单元格填充前一行的艺术家单元格。
然后它(testCSVFunc()
)调用enterFrame()
enterFrame()
重复调用finalCSV,在文本字段中添加“艺术家 - 标题”行。
...直到指定时间过去。即1000 / 24 - 2 - 2 =约。 38毫秒 - 相当于每秒 24 帧的帧的持续时间略小。不知道为什么“ - 2 - 2”,但我的想法是让每一帧都花费一些时间让Flash做其他事情(比如渲染舞台)。
当38毫秒被用于处理时,它会停止(return
语句) - 并且在你再次点击之前不再做任何事情(此时它将从{{1}调用) } - 继续它停止的地方 - 在testCSVFunc()
)。 savedIndex
将继续处理数据,直到testCSVFunc
不再为真 - 即,当CSV中没有剩余项目时。
我猜这个想法是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吗?它们允许在没有解决方法的情况下创建同时执行的线程。