非同期処理を直列化する in ActionScript

非同期処理を同期処理のように直列化したいということはよくあることで、async.jsやjsDeferredのようなライブラリがある場合ならそれを使えばよいが、言語によっては信頼できるライブラリがなかったりする。
そういう場合は自力で直列化するコードを書く他ないが、単純なものならそう難しくないのでActionScriptでやってみた*1。エラーハンドリングをしようと思うともう少し複雑になるが、単に直列化したいだけならこれで十分だろう。

package
{
  import flash.display.Sprite;
  import flash.text.TextField;
  import flash.utils.setTimeout;
  
  public class AsyncExample extends Sprite
  {
    private var text :TextField;
    
    private function puts(s :String) :void {
      text.appendText(s + "\n");
      trace(s);
    }
    
    public function AsyncExample()
    {
      super();
      
      text = new TextField();
      text.x = 100;
      text.y = 0;
      text.scaleX = 3.0;
      text.scaleY = 3.0;
      addChild(text);
      
      var tasks :Vector.<Function> = new Vector.<Function>();
    
      var next :Function = function() :void {
        var task :Function = tasks.shift();
        if(task !== null) {
          task();
        }
      };
      
      tasks.push(function() :void {
        setTimeout(function() :void {
          puts('one');
          
          next();
        }, 1000);
      });
      tasks.push(function() :void {
        setTimeout(function() :void {
          puts('two');
          
          next();
        }, 100);
      });
      tasks.push(function() :void {
        setTimeout(function() :void {
          puts('three');
          
          next();
        }, 1000);
      });
      tasks.push(function() :void {
        setTimeout(function() :void {
          puts('four');
          
          next();
        }, 100);
      });
        
      next();
    }
  }
}

wonderfl:

Serialize asynchronous methods - wonderfl build flash online

*1:他の言語でも同様のアプローチで実装できると思う。