pirosikick's diary

君のハートにunshift

jquery1.5のDeferred Object

Deferred Objectとは

jQuery.Deferred, introduced in version 1.5, is a chainable utility object that can register multiple callbacks into callback queues, invoke callback queues, and relay the success or failure state of any synchronous or asynchronous function.

Deferred Object – jQuery API

「jquery1.5からの新機能で、複数のコールバック関数をキューに保持・実行でき、どんな同期・非同期の関数の成功・失敗などの状態をリレーできる。」
通常のコールバック1つのイベントや成功・失敗などのトリガーに対して1つしか設定できないですが、このDeferred Objectを使うと複数設定できるようになります。

メリット
  • 複数のコールバックを設定できるので、「別のコールバックが既に設定されていないか」ということを気にしなくてよい。
  • 設定した他のコールバックが実行中または全て実行完了後でも、新しいのコールバックを追加できる。

使ってみる

jQuery1.5では、jQuery.ajax()やjQuery.get()などの一部のAPIで、Deferred Objectを使ったコールバックの設定・呼び出しが実装されている。

jQuery.get()

簡単にXHRできるjQuery.get()で試してみる。成功時はsuccess()、失敗時はerror()、完了時はcomplete()でコールバックを設定でき、これらを複数呼び出すことで複数のコールバックを設定できる。

// 成功時コールバックを3つ設定
$.get("sample.html", function () {
    /* 成功時コールバックその1 */
}).success(fucntion () {
    /* 成功時コールバックその2 */
}).success(function () {
    /* 成功時コールバックその3 */
});

また、下記のように時間差で設定してもちゃんとコールバックは呼ばれるようになっている。

var jqxhr = $.get("sample.html", function () {
    /* 成功時コールバックその1 */
}).success(fucntion () {
    /* 成功時コールバックその2 */
});

・・・(この間にXHR通信が完了していても、、)・・・

jqxhr.success(function () {
     /* 成功時コールバックその3 */
     /* このコールバックはちゃんと実行される */
});

jQuery.DeferredとjQuery._Deferred

jQuery.DeferredとjQuery._Deferredを使うと自分でDeferred Objectを定義できる。jQuery.Deferredは2つのトリガー(resolve, reject)jQuery._Deferredは1つのトリガー(resolveのみ)があるDeferred Objectを作成できる。

jQuery.Deferred
var deferred = jQuery.Deferred();

deferred.then(function () {
    /* 成功時コールバックその1 */
}, function () {
    /* 失敗時時コールバックその1 */
}).done(function () {
    /* 成功時コールバックその2 */
});

// 成功時コールバックを実行
deferred.resolve();

// 失敗時コールバックを実行
deferred.reject();
jQuery._Deferred
var deferred = jQuery._Deferred();

deferred.done(function () {
    /* コールバックその1 */
}).done(function () {
    /* コールバックその2 */
}).done(function () {
    /* コールバックその3 */
});

// コールバックを実行
deferred.resolve();

ちなみにjQuery.Deferredで作られるオブジェクトはjQuery._Deferredで作られるオブジェクトを2つ使っているだけ。jQuery.get()はsuccess, error, completeの3つのトリガーあるのでjQuery.DeferredとjQuery._Deferredを組み合わせて実装されている。詳しくはgithubにあるソース(src/core.jsやsrc/ajax.jsがおすすめ)を見ると詳しくわかります。

まとめ

  • jQuery.DeferredとjQuery._Deferredを使えばかなりカスタマイズ出来そう。
  • イベントのオブザーバーに使えそう
  • まだまだいろんな用途が出てきそう
  • 他のjQuery1.5のAPIを利用していないので、jQuery.DeferredとjQuery._Deferredの実装だけ抜けば1.4でも使えそう

余裕が出たらWebDatabaseで応用してみよーと。ではでは。