理解有角度的承诺

时间:2014-12-03 12:35:46

标签: javascript angularjs

我正在学习Angular,但在理解某一点方面遇到了麻烦。我想从我的服务器获取数据。我使用了这段代码(来自angular' doc):

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对象(我必须编写" 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;

谢谢

3 个答案:

答案 0 :(得分:4)

承诺是一种在没有 blocking 的情况下处理异步请求的方法。在执行更多代码之前,不再等待缓慢的操作(如等待服务器响应),而是返回 promise 并继续执行代码。

因此,当您在上面的代码中致电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, {}

修改

回应你的评论:

  

为什么收到的响应包含完整的promise对象而不仅仅包含数据?   因为我在success函数中返回数据。

您收到的响应 包含承诺,但您的功能 会返回承诺。在您的示例中,serverAccepted被指定为myFunction()的返回值,这是一个承诺,不会更改

该行:

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

根本没有做任何事情 - 从.then().success()函数返回值只有在您要将多个调用链接到.then()时才有用 - 它提供了一种在不增加嵌套回调金字塔的情况下操纵值的方法。 从承诺回调中传递值(传递给.then().success()的函数)不会更改承诺本身(在您的情况下为serverAccepted)。

例如:

假设您服务器上的http GET some/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.

答案 1 :(得分:2)

  

当我调用此函数时,它工作正常,我得到了服务器的答案,但我得到了完整的promises对象

听起来你在做这样的事情:

var data = service.myFunction();

以上在同步世界中会很好,但是在异步操作的情况下,这不是正确使用的承诺。相反,您应该使用返回的promise then/success方法:

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

答案 2 :(得分:0)

$http请求,返回一个带有两个$ http特定方法的promise:成功和错误。 success函数等待,直到请求成功完成(这意味着在$http promise解析之后),并且error函数将仅在$ http promise被拒绝后执行。