我正在学习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;
谢谢
答案 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被拒绝后执行。