2011-11-10 10 views
27

は、簡単な繰延オブジェクトを作成してみましょう:Deferredオブジェクトとそれ自身の約束オブジェクトの違いは何ですか?

defer = $.Deferred(function (defer) { 
    setTimeout(defer.resolve, 3000); 
}); 

上記繰延オブジェクトが3秒間「保留」状態になり、その後、「解決」状態に切り替わります(にバインドされたすべてのコールバックを、その時点でそれが呼び出されます)。

のもその繰延オブジェクトの約束を取得してみましょう:

promise = defer.promise(); 

は、繰延オブジェクトが解決されると呼び出さしようとしているコールバックを追加するために、我々は.done().then()を使用することができます。ただし、このメソッドは、Deferredオブジェクト自体またはその独自の約束オブジェクトでの両方を呼び出すことができます。

defer.then(handler); 

または両方の場合において

promise.then(handler); 

handler関数が呼び出される(この場合は3秒後)。

我々は$.whenを使用する場合、我々は再び遅延オブジェクト自体またはその約束オブジェクト渡すことができます。

$.when(defer).then(handler); 

又は

$.when(promise).then(handler); 

を再び、コードの上記の二つの線の間の差がありません。

ライブデモ:http://jsfiddle.net/G6Ad6/

だから、私の質問は、私たちが繰延オブジェクト自体に.then().done()などを呼び出すことができ、我々は$.when()にその繰延オブジェクトを渡すことができますので、以来、.promise()のポイントは何ですかれます約束オブジェクトを取得していますか?約束オブジェクトの目的は何ですか?機能にこのような冗長性が存在するのはなぜですか?

答えて

23

.resolve().reject()メソッドを使用しないで、遅延値の "密封"コピーが作成されます。 the documentationから:

deferred.promise()方法は、非同期関数は、その内部要求の進行または状態に干渉する他のコードを防止することを可能にします。

値が変更されても意味がない場合に使用されます。たとえば、jQueryがAJAX要求を行うとき、それは約束オブジェクトを返します。内部的には.resolve()は、元のDeferredオブジェクトの値で、ユーザーは約束でそれを観察します。

+1

ああ、それはそれを説明する密封コピー* duh *です。 –

+1

[docs](http://api.jquery.com/Types/#Promise): "Promise Object - このオブジェクトは、以下のメソッドのサブセットを提供します。ユーザーがDeferredの状態を変更しないように、Deferredオブジェクト(次に、done、fail、always、pipe、state) –

2

Deferredオブジェクトの "約束"を使用する場合、オブザーバ(例の解決を待っているオブジェクト)はDeferredオブジェクト自体に直接アクセスできないため、たとえば、 "解決"のメソッドを呼び出すことはできません。そのDeferred。それはオリジナルのDeferredを保護する方法です。

0

Deferredを使用すると、状態setを制御できます。

Promiseについて言えば、状態を読み、コールバックを添付することができます。 get

関連する問題