2013-01-18 91 views
17

我發現這個代碼片段,做什麼,我希望它:jQuery的承諾和骨幹

var promise = this.model.save(); 
$.when(promise).then(function() { 
    console.log(promise.responseText); 
}); 

我想從我的骨幹呼籲this.model.save()找回responseText。此代碼記錄在here。但它不記錄任何東西,即使我在console.log()調用中拉出一個原始文本字符串。

有人能請外行解釋什麼是jQuery的承諾嗎?我已經閱讀過關於它們的內容,但我不認爲自己完全瞭解它們。這可能會幫助我理解爲什麼此代碼不適合我。如果我在console.log(promise)之間的第一和第二行代碼,那麼我得到responseText。因此,$.whenthen正在發生這種情況,導致此問題出錯。

編輯:

閱讀了這篇文章後,我發現我能做到這一點:

var promise = this.model.save(); 
$.when(promise).then(null, function(obj) { 
    console.log(obj.responseText); 
}); 

但我不明白null代表什麼。 then似乎需要兩個參數,一個成功功能和一個失敗功能。但是,成功功能不是第一?我從服務器收到200響應。

+0

閱讀此http://css.dzone.com/articles/exploring-deferred-and-promise –

+0

它看起來像一個很好的文章。謝謝。 – sehummel

+0

沒有probs :)快樂閱讀.. –

回答

26

所以首先,我很肯定你不需要when部分;從jQuery文檔:

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).

由於承諾有一個then方法已經,你可以這樣做:

this.model.save().then(null, function(obj) { 
    console.log(obj.responseText); 
}); 

(上面的代碼恰如一個英文句子,這一事實是一大優勢使用Deferreds,至少對我來說)。

至於你的null的論點,文檔再次很清楚。有三個簽名then(而這僅僅覆蓋不同的jQuery版本,任何給定的版本具有以下):

deferred.then(doneFilter [, failFilter ] [, progressFilter ])

deferred.then(doneCallbacks, failCallbacks)

deferred.then(doneCallbacks, failCallbacks [, progressCallbacks ])

正如你可以看到,所有的三個第一把「完成」功能,故障功能第二。這似乎意味着你正在失敗,這是令人困惑的。避免此問題的一種方法是根本不使用then。相反,請嘗試以下操作:

this.model.save().always(function(obj) { 
    console.log(obj.responseText); 
}); 

這將使您的函數被調用,不管發生了什麼。但是,你應該弄清楚是怎麼回事,所以你可能要改爲添加成功和失敗回調做一些調試:

this.model.save().done(function() { 
    // Success case 
}).fail(function() { 
    // Failure case 
}); 
+0

使用jQuery的推遲,而不是簡單的骨幹回調,像這樣的優點是什麼? 'this.model.save({成功:函數(){ }錯誤:函數(){ }});' – Ingro

+2

這只是風格真的。如果你正在做複雜的事情(比如說說做兩個AJAX調用,其中第二個需要從第一個調用返回的數據),那麼延遲樣式可以讓你做到非常優雅。否則,這實際上只是你想要如何設計你的代碼的問題。真的,這甚至不是一個特定於骨幹的問題;在簡單的舊jQuery中,您還有'$ .ajax({success:handler});'vs,'$ .ajax({})。done(處理程序)'可供選擇。 – machineghost

+0

@machineghost。非常感謝你的迴應。這解釋了很多。 – sehummel

7

因爲this.model.save返回一個承諾,你可以做以下代替:

this.model.save() 
    .done(function(response) { 
     console.log("Success!"); 
    }) 
    .fail(function(response) { 
     console.log("Error!"); 
    }); 

(這比整個$.when容易一點)

我的猜測是,雖然你的迴應返回一個200碼,它仍然是「失敗」,因爲響應數據類型與您期望的不匹配(在$.ajax調用中的dataType屬性中設置了什麼)。

0

我使用承諾的忠實粉絲,我想許手段非常類似的東西在不同的包裝。

要回答你的問題,以前的答案沒有,「then」函數是一個promise的函數,「when」函數是一個失敗保存,如果該對象不是承諾,則「when (obj)「將確保它是一個承諾,以便您可以使用優雅的xxx.then(success(){},error(){})。

順便說一句,machineghost說的「延遲」是讓你使用promise的包。 開始瞭解承諾以及如何使用它。看看這個教程。它非常清楚地解釋每件事情,這是使我如此承諾的文章。現在 http://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/

,如machineghost說,看來你同步調用得到一個錯誤,根據REST API文檔,https://parse.com/docs/rest#(不知道這是否是一樣的骨架),服務器將響應JSON對象爲以下格式的「創造」的要求:

{"createdAt": "2011-08-20T02:06:57.931Z","objectId": "Ed1nuqPvcm"} 

我的猜測是,也許您的服務器沒有響應與正確的JSON請求,所以保存()認爲操作失敗,因爲沒有「createAt 「領域,事件認爲你的服務器確實創建了該項目。