無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

非同期処理の待ち合わせ

非同期処理の実行完了を待ち合わせるユーティリティを書いてみました。

要件

複数の非同期処理を実行し、すべての処理の実行完了後に特定の処理を実行したい。

実装

JavaScriptはシングルスレッドで動作しているらしいので同期化は不要。こんなのでいいはずです。

  • コンストラクタで「すべての処理の実行完了後に行う処理」と「待つ処理の数」を渡す。
  • 非同期処理で実行する関数にWait#createCallBack()で処理の完了を通知する機能を付加して実行。(または、実行完了後にWait#createCallBack()で作成した関数を実行し、処理の完了を通知する。)
  • 非同期処理の実行後に、完了した処理数のカウンタを増やし、「待つ処理の数」と同じになったら、「すべての処理の実行完了後に行う処理」を実行する。
/***
 * 複数の非同期処理の実行を待ち合わせるユーティリティ
 * @param {Function} finish すべてのコマンドの実行完了後に呼び出される。
 * @param {Integer} commandLength コマンドの数。
 */
function Wait( finish, commandLength ) {
  this.count = 0;
  this.commandLength = commandLength;
  this.finish = finish;
}
Wait.prototype = {
    /**
     * 処理完了を通知するコールバック関数を生成する。
     * 引数でコールバック関数が渡された場合、その関数に処理完了を通知する機能を付加する。
     * @param {Function} callback 委譲先コールバック関数。
     */
    createCallBack: function( callback ) {
        var thiz = this;
        return function( arg1, arg2, arg3, arg4, arg5,
            arg6, arg7, arg8, arg9, arg10  ){
            try {
               if ( callback ) {
                    callback( arg1, arg2, arg3, arg4, arg5,
                        arg6, arg7, arg8, arg9, arg10 ); // これはひどい。
               }
            } finally {
                thiz.count += 1;
                if ( thiz.count == thiz.commandLength ) {
                    // 指定回数の呼び出しが完了したら
                    // コールバック関数を実行する。
                    thiz.finish();
                }
            }
        };
    }
}

サンプル

以下のような感じで使います。

var stdout = document.getElementById("stdout");

// Wait オブジェクトを作成。
// 引数で待ちあわせ終了時に実行する処理と待ち数を指定する。
var wait = new Wait( function() {
    stdout.innerHTML += "<br/>end.";
}, 100 );

for ( var i = 0; i < 100; i++ ) {
    // 0〜10秒の間でランダムにxを出力。
    // 実行する関数に待ち合わせ完了通知機能を付加する。
    setTimeout( wait.createCallBack( function() {
        stdout.innerHTML += "x";
    }), Math.random() * 10000 );
}

確認はこちらから。