2014-12-03 85 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