jQuery で HTTP 接続するときの書き方2012年12月16日 19時41分

12 月 13 日に Kyoto.js の第 3 回 meetup で、「jQuery で HTTP 接続するときの書き方」と題した 5 分間のライトニングトークを行いました。以下にその内容を一部再構成して収録します。


こんにちは、nanto_vi です。今日は jQuery で HTTP 接続をするときの書き方について話します。

皆さん jQuery を使うことも多いかと思います。jQuery で HTTP 接続をするとき、古いサンプルだと次のような書き方が載っています。

$.ajax({
    url: '/foo/bar',
    data: { baz: 'qux' },
    success: function (data) {
        console.log(data);
    },
});

接続完了時の処理をコールバック関数として $.ajax() に渡してやる形ですね。しかし、現在この書き方は非推奨となっており、替わりに次のように書きます。

$.ajax({
    url: '/foo/bar',
    data: { baz: 'qux' },
}).done(function (data) {
    console.log(data);
});

$.ajax() の返り値に対して、done メソッドで接続完了後の処理を登録する形です。この書き方の何がいいかといえば、返り値を使いまわしたり done メソッドを複数回呼び出したりして、完了後の処理を後から追加できるところです。昔の書き方では完了後の処理がコールバック関数として $.ajax() の内部に格納されていましたが、現在は「完了後の処理」だけを $.ajax() の外部に (「プロミス」として) 取り出すことが可能になったわけですね。

今「内部の処理を外部に取り出す」と言いましたが、この言葉はどこかで聞き覚えがありませんか。そう、内部イテレータと外部イテレータです。

内部イテレータは、オブジェクトが個々の要素に対する処理を受け取り、オブジェクト内部で自身の各要素に適用させる形、

// 内部イテレータの使用例
$('p').each(function () {
    doSomethingWith(this);
});

外部イテレータは、オブジェクトから「各要素を列挙する」という機能だけをオブジェクト外部に取り出す形です。

// 外部イテレータの実装例と使用例
$.fn.iterator = function () {
    var i = 0, n = this.length, self = this;
    return {
        hasNext: function () { return i < n; },
        next: function () { return self[i++]; }
    };
};

var iterator = $('p').iterator();
while (iterator.hasNext()) {
    var element = iterator.next();
    doSomethingWith(element);
}

JavaScript 1.7 以降ではジェネレータという機能により、内部イテレータのような書き方で外部イテレータを生成することができます。

さて、「処理を内部に持ってしまっている」というのは、イベントハンドラの登録も同じですね。

$(document).on('click', function (event) {
    ...
});

イベント発生時の処理をコールバック関数として jQuery オブジェクト内部に渡していますが、これを外部に持ち出すことはできないのでしょうか。

実はそれを可能にするものとして Reactive Extensions (Rx) があります。Rx 入門記事の図にもあるように、Rx を使うと空間にまたがる要素 (配列など) の列挙と時間にまたがる要素 (イベントなど) の列挙を統一的に扱うことができます。

Reactive Extensions は主に .NET Framework 上で利用されていますが、JavaScript での実装として RxJS が公開されています。

ObserverパターンとIteratorパターンは同じだったんだよ!なんだってー!

neue cc - .NET Reactive Framework メソッド探訪第一回:FromEvent

そう、ObserverパターンとIteratorパターンは同じなのだよ、ナンダッテー!

neue cc - Reactive Extensions for JavaScript

(このあたりで時間切れ)