ウェイトを掛けながらシーケンシャルに関数を実行する

たとえばjavascript

  1. このページに行って
  2. テキストボックスに「ほげほげ」と入力して送信ボタンを押し
  3. 結果のhtmlから id=result な要素のテキストを取得する

というような処理を書くとき、それぞれの動作の間にサーバからの返答がどれぐらいかかるかわからないので、 でまぁ多めに見積もって5秒後だったら大丈夫だろうっていうので、

var f1 = function()
{
  location.href="http://example.com/";
  setTimeout(f2, 5000);
}

var f2 = function()
{
  $("#text1").val("ほげほげ");
  $("#form1").submit();
  setTimeout(f3, 5000);
}

var f3 = function()
{
  alert( $("#result").text() );
}

こんなコードを書くのが普通かな。でもこれはダサイので、こんな風に書きたい。

seq_execute(f1, f2, f3);

そんな seq_execute の実装はこんなカンジ

function seq_execute(/* funcs */)
{
    var i=0;
    var self_arguments = arguments;

    var loop_func = function(f)
    {
        var result = f();
        if( result ) ++i;

        if( i < self_arguments.length )
            setTimeout( function(){loop_func(self_arguments[i]);}, 200 );
    };

    loop_func(self_arguments[i]);
}

var f1 = function()
{
  location.href="http://example.com/";
  return true;
}

var f2 = function()
{
  if( $("#text1").length == 0 )
    return false; // ページ遷移が終わるまで待つ

  $("#text1").val("ほげほげ");
  $("#form1").submit();
  return true;
}

var f3 = function()
{
  if( $("#result").length == 0 )
    return false; // ページ遷移が終わるまで待つ

  alert( $("#result").text() );
  return true;
}