jQuery1.5以降ではDefferedオブジェクトというものが導入されて,非同期通信に対するコールバックなどをすっきり書けるようになった,らしいです.
参考: http://qiita.com/items/f3269bf91b192bc49395
早速使ってみようとしたところ,はまってしまいました.
出来そう,起こりそうだと思っていること
$.ajaxのドキュメントには,$.ajaxはjqXHR(jQuery XMLHttpRequestを返すとある.
また,
The jqXHR objects returned by $.ajax() as of jQuery 1.5 implement the Promise interface, giving them all the properties, methods, and behavior of a Promise (see Deferred object for more information).
jqXHRオブジェクトはPromiseインタフェースを実装しているらしい.
ドキュメントによると
This object provides a subset of the methods of the Deferred object (then, done, fail, always, pipe. isResolved, and isRejected) to prevent users from changing the state of the Deferred.
PromiseはDeferredのサブセットであり,doneやpipeなどのメソッドを持つ.
従って,$.ajax({url:'hoge'}).done(callback);のような使い方が出来るはずである,と思う.
実際に起きたこと
Qiitaの上でChromeのコンソールを開き,jQuery(1.7.2のようだ)と戯れた結果,以下の様に$.ajaxはjqXHRオブジェクトではなく,Defferdオブジェクトを返した.また,戻ってきたオブジェクトは,doneなどのメソッドを持たない...どういうことなの..
$.ajax({url:"http://qiita.com"}) // $.ajaxの戻り値はDeffered型?
Deferred
_next: null
callback: Object
__proto__: Object
_fire: function (a,b){var c="ok";try{b=this.callback[a].call(this,b)}catch(d){c="ng",b=d,Deferred.onerror&&Deferred.onerror(d)}return Deferred.isDeferred(b)?b._next=this._next:this._next&&this._next._fire(c,b),this}
_id: 250149748310446
_post: function (a,b){return this._next=new Deferred,this._next.callback[a]=b,this._next}
call: function (a){return this._fire("ok",a)}
cancel: function (){return(this.canceller||function(){})(),this.init()}
error: function (a){return this._post("ng",a)}
fail: function (a){return this._fire("ng",a)}
init: function (){return this._next=null,this.callback={ok:Deferred.ok,ng:Deferred.ng},this}
loop: function (){var a=arguments;return this.next(function(){return b.apply(this,a)})}
next: function (a){return this._post("ok",a)}
wait: function (){var a=arguments;return this.next(function(){return b.apply(this,a)})}
__proto__: Object
__defineGetter__: function __defineGetter__() { [native code] }
__defineSetter__: function __defineSetter__() { [native code] }
__lookupGetter__: function __lookupGetter__() { [native code] }
__lookupSetter__: function __lookupSetter__() { [native code] }
constructor: function Object() { [native code] }
hasOwnProperty: function hasOwnProperty() { [native code] }
isPrototypeOf: function isPrototypeOf() { [native code] }
propertyIsEnumerable: function propertyIsEnumerable() { [native code] }
toLocaleString: function toLocaleString() { [native code] }
toString: function toString() { [native code] }
valueOf: function valueOf() { [native code] }
$.Deferred() // 上で見たDeffered型らしきものとは,持つメソッドが異なる?
Object
always: function (){return i.done.apply(i,arguments).fail.apply(i,arguments),this}
done: function (){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this}
fail: function (){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this}
isRejected: function (){return!!i}
isResolved: function (){return!!i}
notify: function (){return p.fireWith(this,arguments),this}
notifyWith: function (b,c){return d&&(j?a.once||d.push([b,c]):(!a.once||!e)&&o(b,c)),this}
pipe: function (a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()}
progress: function (){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this}
promise: function (a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}
reject: function (){return p.fireWith(this,arguments),this}
rejectWith: function (b,c){return d&&(j?a.once||d.push([b,c]):(!a.once||!e)&&o(b,c)),this}
resolve: function (){return p.fireWith(this,arguments),this}
resolveWith: function (b,c){return d&&(j?a.once||d.push([b,c]):(!a.once||!e)&&o(b,c)),this}
state: function (){return e}
then: function (a,b,c){return i.done(a).fail(b).progress(c),this}
__proto__: Object
__defineGetter__: function __defineGetter__() { [native code] }
__defineSetter__: function __defineSetter__() { [native code] }
__lookupGetter__: function __lookupGetter__() { [native code] }
__lookupSetter__: function __lookupSetter__() { [native code] }
constructor: function Object() { [native code] }
hasOwnProperty: function hasOwnProperty() { [native code] }
isPrototypeOf: function isPrototypeOf() { [native code] }
propertyIsEnumerable: function propertyIsEnumerable() { [native code] }
toLocaleString: function toLocaleString() { [native code] }
toString: function toString() { [native code] }
valueOf: function valueOf() { [native code] }