My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
AjaxDeferred  
JSDeferred を使って jQuery.ajax を拡張します。非同期メソッドのチェーンとエラーハンドリングを容易にします。
JSDeferred, jQuery.ajax, jQuery.get, jQuery.post, jQuery.getJSON, jQuery.getFeed, jQuery.getData, jQuery.postData
Updated Sep 10, 2009 by nakajim...@gmail.com

JSDeferred とは

JSDeferred は、非同期処理をメソッドチェーンで記述することで、非同期処理の順序や値の受け渡し、エラーハンドリングの複雑さを解消するライブラリです。作者は cho45 さんです。JSDeferred の特徴や優位性は、JSDeferred による非同期処理 Hitoshi Amano で紹介されていますので、見てください。

jQuery.ajax のメソッドチェーンとエラーハンドリング

opensocial-jquery は、JSDeferred を使って jQuery.ajax を拡張します。そして、次のように jQuery.ajax とそのショートカットのメソッドチェーンとエラーハンドリングを容易します。

  $.getJSON('http://example.com/foo.json').next(function(foo) { // -- (1)
    console.log('next', foo);
    return $.getJSON('http://example.com/bar.json').next(function(bar) { // -- (2)
      console.log('bar', bar);
      return [foo, bar];
    });
  }).next(function(foobar) { // -- (3)
    console.log('foobar', foobar[0], foobar[1]);
  }).error(function(status) { // -- (4)
    console.log('error', status);
  });

はじめに (1) の jQuery.getJSON で /foo.json のデータを取得します。成功したときは (2) に続きます。失敗したときは (4) でエラーハンドリングして終了します。次に (2) jQuery.getJSON で /bar.json のデータを取得します。成功したときは (3) に続き、このときの引数が /foo.json と /bar.json の配列になります。失敗したときは (4) でエラーハンドリングして終了します。(4) のエラーハンドリングは、jQuery.ajax の error イベントの status か、throw したオブジェクトが引き渡されます。

jQuery.ajax の非同期のコールバックを next メソッドでチェーンして、その順番どおり実行させることができます。このとき、上から下に向かって、ネストしているときは、親から子に向かってという順番になります。そして、そのチェーンの中でエラーが発生したとき、error メソッドでエラーをハンドリングできます。チェーンのはじめや途中でエラーが発生したときは、そこでチェーンが中断するので、エラーのハンドリングは 1つで済むということです。また、jQuery.ajax のショートカットは、エラーのコールバックをサポートしていませんが、jQuery.getJSON や jQuery.post でも error メソッドを使ってエラーのハンドリングができます。

実例: 友達リストとデータをまとめて取得する

jQuery.ajax を使って VIEWER の友達リストとそのデータをまとめて取得できます。はじめに友達リストを取得し、次にそのデータを取得してまとめています。また、エラーハンドリングも1箇所にまとめています。

  $.ajax({
    url: '/people/@viewer/@friends',
    data: {},
    dataType: 'data'
  }).next(function(people) {
    return $.ajax({
      url: '/appdata/@viewer/@friends',
      data: {},
      dataType: 'data'
    }).next(function(data) {
      return $.map(people, function(person) {
        if (data[person.id])
	  person.data = data[person.id];
	return person;
      });
    });
  }).next(function(people) {
    $.each(people, function(i, person) {
      console.info(person.id);
      console.info(person.data);
    });
  }).error(function(e) {
    console.error(e);
  });

関連リンク

Comment by syujik...@gmail.com, Mar 20, 2009

自分が書いたソース内で直接 JSDeferred を呼び出したいのですが (例 :Deferred.define();) Deferred なんてねーよってfirebugに 怒られます。 opensocial-jquery.jsの内部を見たところ jquery のコンテキスト内 で Deferred が定義されているのだと思うのですが、$.ajax などを 使わずとも直接 Deferred にアクセスする方法はないでしょうか? var myfunc = function(){

Deferred.define(); // <- Deferredなんてねーよエラー next(function(){
// do A
}).next(function(){
// do B
});
}

Comment by project member nakajim...@gmail.com, Mar 21, 2009

> $.ajax などを 使わずとも直接 Deferred にアクセスする方法はないでしょうか? > Deferred.define(); // <- Deferredなんてねーよエラー next(function(){

Deferred オブジェクトは意図的に見えないようにしています。$.ajax 以外でも deferred を使いたいケースがありそうかもと気にしていました。差し支えなければ、どんなときに deferred を使おうとしているか、ご紹介いただけないでしょうか。

Comment by syujik...@gmail.com, Mar 22, 2009

> どんなときに deferred を使おうとしているか、ご紹介いただけないでしょうか。

独自のロジック内で同期を行いたい場合です。(同期処理の開始がjqueryを用いないロジックです)

実際には、 $.deferred.next(...) のようにできれば、Deferred を自分で直接インスタンス化する必要はありません。

Comment by project member nakajim...@gmail.com, Mar 22, 2009

> 独自のロジック内で同期を行いたい場合です。(同期処理の開始がjqueryを用いないロジックです) > 実際には、 $.deferred.next(...) のようにできれば、Deferred を自分で直接インスタンス化する必要はありません。

コメントありがとうございます。意図を理解できました。次のリリースで、上記か何らかの形で対応します。忘れることがないように issues 化しました。

http://code.google.com/p/opensocial-jquery/issues/detail?id=3

Comment by project member nakajim...@gmail.com, Apr 18, 2009

最終的に、次のメソッドで対応しました。1.0.2 に含めます。

jQuery.wait jQuery.next jQuery.call Deferred.wait Deferred.ajax Deferred.get Deferred.getJSON Deferred.getFeed Deferred.getData Deferred.post Deferred.postData

http://code.google.com/p/opensocial-jquery/issues/detail?id=3


Sign in to add a comment
Powered by Google Project Hosting