【问题标题】:Asynchronous function call in FlexFlex 中的异步函数调用
【发布时间】:2010-10-08 12:05:18
【问题描述】:

是否可以在 Flex 中异步调用函数?我想定期解析文件而不阻塞应用程序的其余部分,推荐的方法是什么?

【问题讨论】:

    标签: apache-flex actionscript-3 actionscript asynchronous


    【解决方案1】:

    Actionscript 不支持多线程,我认为这是您在这里真正要问的问题。

    虽然该功能不是 actionscript(或 Flex)所固有的,但您可以使用事件和计时器设置模拟系统。

    我对你的确切问题有点不清楚,所以我会给出两个答案:

    1) 您希望每隔几秒处理一次文件以对任何更改采取行动。

    在这种情况下,您需要做的就是设置一个计时器来定期检查文件:

    var fileTimer:Timer = new Timer(5000);
    fileTimer.addEventListener(TimerEvent.TIMER, checkFile);
    
    ...
    
    private function checkFile(event:TimerEvent):void {
      // read the file and do whatever you need to do.
    }
    

    2) 您想要解析一个非常大的文件,但不希望应用程序在执行此操作时挂起。

    如果你想在后台处理文件,同时保持主应用程序响应,那么我可能会创建一个函数来解析文件的几行,然后发送一个事件并返回。侦听该事件并启动一个计时器,该计时器将等待几毫秒,然后再次调用该函数以解析下一组行。

    这会中断对大文件的解析,并有足够的停机时间来保持应用程序的其余部分平稳运行。您必须使用计时器间隔和一次解析的行数,以在响应能力和解析文件所需的时间之间取得良好的平衡。

    希望这是有道理的!

    【讨论】:

    • Flash Player 在 ActionScript 运行时不会呈现。 validateNow() 将强制 Flex 组件进行绘制,但它不会真正呈现到屏幕上,直到一个框架中的所有 ActionScript 完成运行。
    • 你说的很对,我已经从我的答案中删除了错误的代码,这样没有人会尝试使用它。
    • 更好的方法是将解析例程拆分为递归方法调用,使用 callLater 进行调用
    【解决方案2】:

    最简单的答案是使用callLater 例程 - 请参阅一些文档here

    callLater( parseFile, [filename] );
    
    ...
    
    public function parseFile( filename : String ) : void
    {
        // parse the file
    }
    

    另一种方法是使用在flash.utils 包中定义的setTimeout 调用。这个允许您在经过指定的时间后调用例程。使用此例程,您可以设置 parseFile 函数以重复调用自身,从而为您提供所需的定期间隔:

    parseFile( filename );
    
    ...
    
    public function parseFile( filename : String ) : void
    {
        // parse the file
    
        // call this function again in 5 seconds
        setTimeout( parseFile, 5000, filename );
    }
    

    【讨论】:

      【解决方案3】:

      还有一个setInterval 函数,它会定期调用一个函数,这可能很有用。

      【讨论】:

        【解决方案4】:

        有趣的是,就在昨天我described a solution这个问题回复了different question

        【讨论】:

          【解决方案5】:

          setTimeout 和 setInterval 都已弃用。

          Timer 类不仅允许延迟,还允许 repeatCount:它会抛出多少次 TIMER 事件并重新开始倒计时。据推测,在做任何你想做的事情之前,你会在事件中调用 myTimer.stop(),然后在完成后调用 myTimer.start()。

          private function newLinesToParse() : void
          {
              myTimer = new Timer(30000, 9999);
              myTimer.addEventListener(Timer.TIMER, myTimerTick);
              myTimer.start(); 
          }
          
          private function myTimerTick(event : Event) : void
          {
              myTimer.stop();    // or (event.currentTarget as Timer).stop();
          
              // do a few lines
          
              if (anyMoreLines)  
                  myTimer.start();
              else
                  myTimer = null;
          }
          

          干杯

          【讨论】:

          【解决方案6】:

          您需要一个名为Green threads 的概念。有一个green threading lib,但我没用过。

          我为导入过程(1 - 5 分钟)所做的实现实际上跟踪了执行所花费的时间,并允许每个周期可配置的时间量。这允许您选择丢弃的帧数(我们只是在更新模态进度条)。我还使用一个通过 IViewCursor 的 ICollectionView 运行的版本对其进行子类化,并使用每个项目触发事件。

          由于它与商业产品有关,我无法提供源代码,但这个概念很容易实现。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-01-20
            • 2012-07-25
            • 2015-03-19
            • 2015-01-22
            • 2020-03-09
            • 2013-03-28
            相关资源
            最近更新 更多