我是新来的角的$ Q,我试图建立一个服务,使API调用并返回给控制器。
问题:无论我怎么似乎格式化,服务收益
权利之前它得到$ http.get(...)
服务:
//方法:查询新的,拿现有的 makeRequest的:功能(URL,如下){ //创建承诺 变种推迟= $ q.defer(); $ http.get(URL,{ params:一个{ 下面的:JSON.stringify(以下) } }) 。然后(功能(RES){ 的console.log(RES); deferred.resolve(res.data); }); 返回deferred.promise; }, getFeed:功能(用户){ 的console.log('>> userService [的getUser]:检索用户...'); 如果(!this.activities){ //请求尚未作出,设置用户配置文件。 的console.log('>> userService [的getUser]:无用户存储,因此请求......'); VAR以下= this.compileArray(用户); 的console.log(下面); this.activities = this.makeRequest(API /网络/活动,下面); }; //返回存储在服务myObject的 返回this.activities; }
控制器
$ scope.recentActivity = activityService.getFeed(配置文件);//也试过activityService.getFeed(配置文件)。然后(功能(RES){ $ scope.recentActivity =资源; 的console.log(RES); });
修改:上午9:40 2015年5月6日
如果可能的话,我想从服务中检索以同样的方式我会在控制器中的活动列表,如果它是新的(使用。然后
)。这是可能的/糟糕的做法?
getFeed:功能(用户){ 如果(!this.activities){ ... }其他{ feedPromise = $ Q(函数(解析){解析(this.activities)}); 的console.log(feedPromise); //返回:{$$状态:对象,则:功能,美中不足的是:函数,最后:功能} feedPromise.then(功能(RES){ 的console.log(RES); //返回:未定义 }); 的console.log(that.activities); //作品,返回的活动列表。 }
解决方案
有没有必要使用 $ q.defer
,除非你正在转换为非基于承诺与回调到基于承诺的API API(即使在当时,它被推荐使用 $ q(功能(解决,拒绝){...})
)。
$ HTTP
已返回一个承诺 - 只是返回的是的(或链接。然后
承诺);
VAR HTT presponsePromise = $ http.get(URL); //返回一个承诺VAR actualDataPromise = HTT presponsePromise.then(功能(RESP){返回resp.data;});返回actualDataPromise;
或较短(典型):
返回$ http.get(URL)。然后(功能(响应){ 返回response.data;});
二,一诺返回API返回的承诺 - 没有结果 - 的马上的,同步。你需要一个。然后
来得到结果。
最后,一旦一个API是异步,它应该总是异步 - 不将其转换为同步或有时同步的API。所以,任何地方,任何方式的数据终端接收,您需要使用。然后
处理程序。
所以,你的服务API可以做成很简单:
makeRequest的:功能(URL,如下){ 返回$ http.get(URL,{PARAMS:{下面的:以下}}) 。然后(功能(响应){ 返回response.data; });},getFeed:功能(用户){ VAR认为这=; VAR feedPromise; 如果(!that.activities){ VAR以下= this.compileArray(用户); feedPromise = this.makeRequest(API /网络/活动,下面) 。然后(功能(活动){ that.activities =活动; 返回活动; }); }其他{ feedPromise = $ Q(函数(解析){解析(that.activities);}); //或者你可能会缓存旧feedPromise和返回 } 返回feedPromise;}
在控制器的使用就像任何其他基于承诺的API:
activityService.getFeed(配置文件) 。然后(功能(活动){ $ scope.recentActivity =活动; });
I'm new to angular's $q and I'm trying to build a service that makes an API call and returns it back to the controller.
Problem: No matter how I seem to format it, the service returns
right before it gets to $http.get(...)
Service:
// methods: query new, get existing
makeRequest: function(url, following) {
// create promise
var deferred = $q.defer();
$http.get(url, {
params: {
"following": JSON.stringify(following)
}
})
.then(function(res) {
console.log(res);
deferred.resolve(res.data);
});
return deferred.promise;
},
getFeed: function(user) {
console.log('>> userService[getUser]: retrieving user...');
if (!this.activities) {
// Request has not been made, setting user profile.
console.log('>> userService[getUser]: No user stored, making request...');
var following = this.compileArray(user);
console.log(following);
this.activities = this.makeRequest('api/network/activities', following);
};
// Return the myObject stored on the service
return this.activities;
}
Controller
$scope.recentActivity = activityService.getFeed(profile);
// also tried
activityService.getFeed(profile).then(function (res) {
$scope.recentActivity = res;
console.log(res);
});
EDIT : 9:40am 05/06/2015
If possible, I'd like to retrieve the activity list in the controller from the service in the same way I would if it were new (using .then
). Is that possible/ bad practice?
getFeed: function(user) {
if (!this.activities) {
...
} else {
feedPromise = $q(function(resolve){ resolve(this.activities) });
console.log(feedPromise);
// returns: {$$state: Object, then: function, catch: function, finally: function}
feedPromise.then(function(res) {
console.log(res);
// returns: undefined
});
console.log(that.activities);
// Works, returns list of activities.
}
解决方案
There is no need to use a $q.defer
unless you are converting a non-promise based API with callbacks into a promise-based API (and even then, it is recommended to use $q(function(resolve, reject){...})
).
$http
already returns a promise - just return that (or a chained .then
promise);
var httpResponsePromise = $http.get(url); // returns a promise
var actualDataPromise = httpResponsePromise.then(function(resp){ return resp.data; });
return actualDataPromise;
or shorter (and typical):
return $http.get(url).then(function(response){
return response.data;
});
Second, a promise-returning API returns the promise - not the result - right away, synchronously. You need a .then
to get the result.
Lastly, once an API is async, it should always be async - don't convert it to a sync or a sometimes-sync API. So, everywhere, all the way to the end recipient of the data, you need to use a .then
handler.
So, your service API can be made quite simple:
makeRequest: function(url, following){
return $http.get(url, {params: { "following": following }})
.then(function(response){
return response.data;
});
},
getFeed: function(user) {
var that = this;
var feedPromise;
if (!that.activities) {
var following = this.compileArray(user);
feedPromise = this.makeRequest('api/network/activities', following)
.then(function(activities){
that.activities = activities;
return activities;
});
} else {
feedPromise = $q(function(resolve){ resolve(that.activities); });
// or you could have cached the old feedPromise and returned that
}
return feedPromise;
}
The usage in the controller is just like with any other promise-based API:
activityService.getFeed(profile)
.then(function(activities) {
$scope.recentActivity = activities;
});
相关推荐
最新文章