javascriptで非同期処理、の続き

http://d.hatena.ne.jp/sunpro/20100501/1272696997

Concurrent.Threadはちょっと大技すぎる、ということで素直にfunctionをchainさせることにします。MooToolsのChainをつかうとこんな感じに。

// イベントをこんな風に書きたい、というのが目的
function playTutorial() {
    message('歩きます。');        // メッセージwindowが開き、クリックすると次に進む
    walk();                       // プレイヤーが歩く。アニメーションが終わると次に進む
    message('歩きました。');
}

var sequence = new Chain();
function chain(fn) {
    sequence.chain(fn);
}
function next() {
    sequence.callChain();
}

function message(msg) {
    document.body.innerHTML = msg;
    document.onclick = function() {
        document.onclick = null;
        next();
    };
}
function walk() {
    var fx = new Fx({ duration: 5000 });
    fx.set = function(now) {
        var text = 'walking';
        for (var i = 0; i < now; i++) {
            text += '.';
        }
        document.body.innerHTML = text;
    };
    fx.start(0, 5).chain(next);
}
['message', 'walk'].each(function(fn) {
    var orig = window[fn];
    window[fn] = function() {
        chain(orig.pass(arguments));
    };
});

// 実行
playTutorial();
next();

値を参照する時にfunctionで包むなどしないといけなくて煩雑な点は妥協する。実際に使うには、sequenceをコールスタックみたいに階層的にする必要があるだろう。