如何在输入框架后停止actionscript中的功能

时间:2013-05-24 07:13:36

标签: actionscript-3 air block

在我的空中程序中,我写了一个这样的函数:

public function getDataFromXml():void
{
    for each()
    {.....} //here may contain thounds of fields and name
}

当然,该功能可能花费10s-20s,所以我想添加一个进度条,然后出现问题,进度条只是被阻止。我发现一帧成本大约40ms,所以原因必须是执行程序帧的间隔,如何解决?

2 个答案:

答案 0 :(得分:0)

这个想法是监视循环中花费的时间,如果这个时间超过帧的允许时间,那么等待下一个。

private var _dummy:Sprite = new Sprite();
private var _data:Array;

public function getDataFromXml():void
{
    var startTime:Number = getTimer();
    const allowedTime:Number = 1000 / stage.frameRate;

    while (getTimer() - startTime < allowedTime && _data.length > 0)
    {
         _data.pop(); //pop your data to remove the treated lines, or keep track of the current index
         //do your treatment here
    }
    if (_data.length == 0)
    {
       //the end
    }
    else
    {
        //wait for the next frame to go on
        _dummy.addEventListener(Event.ENTER_FRAME, onNextFrame);
    }
}

private function onNextFrame(event:Event):void
{
    _dummy.removeEventListener(Event.ENTER_FRAME, onNextFrame);
    getDataFromXml();
}

答案 1 :(得分:0)

问题的主要原因是,尽管Flash尝试遵循它的帧速度,但它必须在一帧中完成所有脚本执行才能转到下一帧。因此,如果您的foreach需要执行40秒,那么Flash将无法传递到下一帧,直到达到40秒。

此问题的主要解决方案是:您必须使此执行异步。 有几种方法可以做到。

第一种方法是在较小的部分中削减执行力。由于您使用循环,通过限制循环可以在一帧中执行的步数,这可以非常简单。基本上,它看起来有点像这样:

private var _getDataIndex:Number;
private var _extractedData:Array;

public function getDataFromXml():void
{
    _getDataIndex = 0;
    _extractedData = new Array();
    this.addEventListener(Event.ENTER_FRAME, getDataFromXmlStep); // You can also use a Timer instead
    for each()
    {.....} //here may contain thounds of fields and name
}

private function getDataFromXmlStep(evt:Event):void
{
  for(var i:int = 0; i < 5; i++) {
    var field:XML = _myXMLData[_getDataIndex];
    if (field == null) {
      getDataFromXmlFinished()
      break;
    }
    {.....} // your code for the field, the result saved in _extractedData
    _getDataIndex++;
  }
}
private function getDataFromXmlFinished():void {
    this.removeEventListener(Event.ENTER_FRAME, getDataFromXmlStep); // You can also use a Timer instead
    // extraction finished
}

如果使用AIR 3.4或更高版本,另一种解决方案是使用Worker。简单地说,您将工作委托给另一个线程,该线程在主代码执行其他操作(管理与窗口的交互)时不会显示任何可以自动转动的内容。 工作人员是一件好事,但受限于因为您需要最新版本的AIR才能使用它们。