$ q.defer()不与角度的服务工作 [英] $q.defer() not working with Angular service

查看:223
本文介绍了$ q.defer()不与角度的服务工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新来的角的$ 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;
   }); 

这篇关于$ q.defer()不与角度的服务工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆