了解安格尔的承诺

Understanding angular's promises

本文关键字:承诺 安格尔 了解      更新时间:2023-09-26

我正在学习Angular,但很难理解一个观点。我想从我的服务器获取数据。我使用了这段代码(来自 angular 的文档(:

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;

谢谢

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

因此,当您在上面的代码中调用myFunction时,它将返回一个 promise 对象。

然后,Promise 提供了一些简洁的方法,用于在服务器响应注册回调以运行代码。这些方法分别针对成功和错误情况进行.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 对象,而不仅仅是数据? 因为我在成功函数中返回数据。

您收到的响应根本不包含承诺,但您的函数返回一个承诺。在您的示例中,serverAccepted被分配了返回值 myFunction(),这是一个承诺,不会更改

该行:

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

实际上什么都不做 - 从.then().success()函数返回值仅在您要将多个调用链接在一起.then()时才有用 - 它提供了一种操作值的方法,而无需不断增加的嵌套回调金字塔。从 promise 回调(传递给 .then().success() 的函数(中返回值不会更改 promise 本身(在您的情况下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.

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

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

var data = service.myFunction();

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

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

$http请求,返回一个承诺,其中包含两种$http特定方法:成功和错误。 成功函数会等到请求以成功完成(这意味着在$http承诺解析之后(,并且error函数只有在$http承诺被拒绝后才会执行。