2011-11-10 61 views
27

讓我們創建一個簡單Deferred對象:Deferred對象和它自己的承諾對象之間有什麼區別?

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

上述Deferred對象將在「未決」狀態3秒鐘,然後切換到「解決」狀態(在該點處結合到所有回調它將被調用)。

我們也檢索Deferred對象的承諾:

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()方法。 From the documentation

deferred.promise()方法允許異步函數阻止其他代碼干擾其內部請求的進度或狀態。

當它對於要修改的值沒有意義時使用它。例如,當jQuery發出一個AJAX請求時,它返回一個promise對象。它在內部是.resolve()是原始Deferred對象的值,用戶遵守該承諾。

+1

啊這是一個封閉的副本*呃* ...解釋它。 –

+1

爲了讓我更加清楚這點,從[docs](http://api.jquery.com/Types/#Promise):「Promise Object - 這個對象提供了一個子集的方法延遲對象(然後,完成,失敗,始​​終,管道和狀態)以防止用戶更改延遲狀態。「 –

2

當使用Deferred對象的「承諾」時,觀察者(例如等待解析的對象)不能直接訪問Deferred對象本身,因此他們不能調用例如方法「Resolve」的方法推遲。這是保護原始延期的一種方式。

0

使用延遲,您可以控制其狀態set

當涉及到承諾,你可以閱讀狀態,並可能附加回調。 get

相關問題