2014-12-03 152 views
2

我正在學習角,但在遇到問題時要了解的一個點。我想從我的服務器獲取數據。我用這個代碼(從角度的文檔):理解角度的承諾

this.myFunction = new function() 
{ 
    var uri = this.getServerUri() + "Connexion/"+login+"/"+CryptoJS.MD5(pass); 

      var promises = $http.get(uri) 
      .success(function(data, status, headers, config) { 
       // this callback will be called asynchronously 
       // when the response is available 
       //alert("success:"+JSON.stringify(data)); 
       return data; 
      }). 
      error(function(data, status, headers, config) { 
       // called asynchronously if an error occurs 
       // or server returns response with an error status. 
       return ""; 
      }); 
      return promises; 
}; 

但我不明白的成功函數的行爲。當我調用這個函數時,它工作正常,我得到服務器的答案,但我得到完整的承諾對象(我必須寫「promises.data」來獲取我的數據)。你能解釋我爲什麼嗎?因爲在成功函數中,我試圖只返回數據。

編輯:我忘了補充我的調用函數:

var serverAccepted = this.MyFunction().then(function(promise) { 
         var objet = promise.data; 
         if(!_.isEmpty(objet)) 
         { 
          userService.setUser(objet, true); 
          return ""; 
         } 
         else return "Error while trying to login on the server"; 

        }); 
     return serverAccepted; 

謝謝

回答

4

一諾是異步請求處理,而不blocking的一種方式。代替等待緩慢操作(如等待服務器響應),在執行任何更多代碼之前,將返回承諾並繼續執行代碼。

因此,當您在上述代碼中調用myFunction時,它將返回一個承諾對象。

的承諾則提供了用於註冊一個回調,當服務器確實響應運行代碼一些巧妙的方法。這些方法分別爲.then()catch(),分別爲成功和錯誤情況。

傳遞函數作爲參數會調用該函數,當服務器響應,你可以用你喜歡什麼樣的數據做。就拿這個例子:

console.log("About to send request"); 
myFunction() 
.then(function (myData){ 
    console.log("Response received", myData); 
}) 
.catch(function (myError){ 
    console.error("Oh dear", myError); 
}); 
console.log("Request sent!"); 

這將記錄以下控制檯:

About to send request 
Request sent! 
Response received, {} 

編輯

在回答您的評論:

爲什麼響應收到包含完整的承諾對象,而不僅僅是數據? 因爲我在成功函數中返回數據。

響應您收到並包含一個承諾不惜一切,但你的函數返回一個承諾。在你的例子中serverAccepted被分配了myFunction()的返回值,這是一個承諾,不會更改

行:

.success(function(data, status, headers, config) { 
    return data; 
}) 

並沒有真正做任何事情 - 從.then().success()函數返回值是唯一有用的,如果你要鏈子多次打電話給.then()在一起 - 它提供了一個沒有不斷增加的嵌套回調金字塔操縱值的方式。 從承諾回調(傳遞給.then().success()的函數)中返回值不會更改承諾本身serverAccepted在您的情況下)。

例如:

假設你的服務器返回的HTTP GETsome/url

{ 
    foo: 'bar', 
    dorks: 12 
} 

當我們使用$http.get這個數據是響應對象中的字段名爲data。大多數時候我們並不關心剩下的東西,如果通話成功,我們只需要數據,所以我們可以從第一個.then()呼叫(通常在您的服務中)返回它,以便任何後續的.then()調用(例如,在控制器內部)可以直接訪問數據對象。

myPromise = $http.get('some/url') 
.then(function (response) { 
    console.log(response); //--> { status: 200, data: { foo:....}} 
    return response.data; 
}) 
.then(function (data) { 
    console.log(data); //--> {foo: 'bar', dorks: 12} 
    return dorks; 
}) 
.then(function (data) { 
    console.log(data); //--> 12 
}) 

console.log(myPromise); //--> promise object with .then() .catch() etc 
//^THIS WILL NOT CHANGE. 
+0

我明白了,但爲什麼收到的響應包含完整的承諾對象,而不僅僅是數據?因爲我在成功函數中返回數據。 – user2088807 2014-12-03 13:07:17

+0

更新並進一步說明。 – 2014-12-03 15:42:20

+0

完美的解釋謝謝! – user2088807 2014-12-04 14:26:31

0

$http請求,返回兩個HTTP $具體方法承諾:成功和錯誤。成功函數等到的要求是成功完成(這意味着$http承諾結算後),和$ HTTP承諾被拒絕後,才error功能將被執行。

2

當我調用此函數,它工作得很好,我得到了服務器的答案,但我得到了充分的承諾對象

聽起來你正在做的事情是這樣的:

var data = service.myFunction(); 

以上在同步世界中會很好,但是在異步操作的情況下,這不正確的使用promise。相反,你應該使用返回承諾then/success方法:

service.myFunction().then(function(data) { 
    console.log(data); 
}); 
+0

帶'then'和'success'是否需要注入'$ q'並設置響應的防禦/解決? – user2936314 2014-12-03 12:44:10

+0

不,'$ http.get()'已經返回一個Promise。你所需要做的就是鏈接'then/success'方法,提供一個回調函數,一旦解決了這個promise,它就會被調用。 – dfsq 2014-12-03 12:45:21

+0

我粘貼了我的調用函數,因爲您可以看到我需要編寫'promise.data'來使我的代碼正常工作。 – user2088807 2014-12-03 12:52:42