在辅助工厂中使用AngularJS $ q promises

时间:2019-02-19 03:15:37

标签: javascript angularjs asynchronous deferred

我正在尝试在AngularJS中何时使用$q时进行总结。到目前为止,我已经在所有服务中使用了它,因此,当我调用Web API时,它可以很好地工作。我想做的事情是减少对API的所有调用,因为我需要在多个地方使用相同的数据,并且每次需要数据时我就一直对API进行ping操作。

现在我有一个服务,该服务获取数据和一个帮助文件,以帮助处理有关数据的相关事宜。

我想要的是使用此助手factory来保存使用它的每个身体所需的数据。

如果在AngularJS运行时数据还没有归还给我,我很难确定从帮助程序文件中分配数据的值。

这是我到目前为止所拥有的。

(function() {
  var app = angular.module("Test", []);
  app.service("githubService", function($http, $q) {
    var deferred = $q.defer();

    this.getAccount = function() {
      return $http.get('https://api.github.com/users/JonDoe');
    };
  });

  app.factory("githubHelper", ["githubService", function(githubService) {
    _gitHubInfo = {};

    githubService.getAccount().then(function(data) {
      _gitHubInfo = data;
    });

    return {
      gitHubInfo: _gitHubInfo
    };
  }]);

  app.controller("Dummy", ["$scope", "githubHelper", "githubService", function($scope, githubHelper, githubService) {
    
    // How do I make it work this way?
    $scope.value = githubHelper.gitHubInfo;
    
    // This is what I'm using now
    githubService.getAccount().then(function(data) {
      $scope.value2 = data;
    });
  }]);
})();
.box {
  border: 1px red solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="Test">
  <div ng-controller="Dummy">
    <div class="box">
      {{value}}
    </div>
    <br />
    <div class="box">
      {{value2}}
    </div>
  </div>
</div>

我想做的就是从githubService控制器中删除Dummy依赖项,并且仅将其存在于githubHelper工厂中,这样我就可以删除对{{1} },然后使用githubService

我需要在gitHubHelper控制器中进行哪些更改才能使Dummy是从$scope.value返回的数据?

2 个答案:

答案 0 :(得分:3)

我的项目中有类似的内容

app.factory("githubHelper", ["githubService", function(githubService) {
    var promise = null;

    function getInfo() {
      if (!promise) {
        promise = githubService.getAccount();
      }
      return promise;
    }

    return {
      getInfo: getInfo
    };
  }]);

githubHelper.getInfo().then(function(data) {})
githubHelper.getInfo().then(function(data) {})
githubHelper.getInfo().then(function(data) {})
...

答案 1 :(得分:-1)

您几乎在那里。问题在于,githubinfo直到您访问它之后才会被填充。您应该做的几乎是githubservice.getaccount,而实际上是githubhelper.getaccount,实际上是(请参阅上面的评论)。将githubinfo设置为$q.deferred,从getaccount返回githubinfo.promise,然后在then

中解决承诺

更新:现在有更多代码! (现在我不在手机上:-D)

(function() {
  var app = angular.module("Test", []);
  app.service("githubService", function($http, $q) {
    this.getAccount = function() {
      return $http.get('https://api.github.com/users/JonDoe');
    };
  });

  app.factory("githubHelper", ["githubService", function(githubService) {
    return {
      gitHubInfo: $q(function(resolve, reject) {
        githubService.getAccount().then(function(data) {
          resolve(data);
        }, reject);
      }
    };
  }]);

  app.controller("Dummy", ["$scope", "githubHelper",
    function($scope, githubHelper) {

      githubHelper.gitHubInfo.then(function(data) {
        $scope.value = data;
      });

  }]);
})();

现在,按原样编写,出于多种原因,我永远不会批准将其作为PR(代码清晰性:return { someProp: function() { /* a bunch of code */} }...。应不惜一切代价避免使用$scope ...并且如上所述,$cacheFactory可以并且应该处理此问题),但是您应该能够大致了解这些思路下可能的工作方式