AngularJS,在服务中使用承诺

AngularJS, using a promise within a service

本文关键字:承诺 服务 AngularJS      更新时间:2023-09-26

我有一个来自项目MVP的"非常胖的控制器"控制器,我想将其重构为更加模块化和划分的代码。

目前,我的控制器中有一个功能,它:

  1. 对 API 进行$HTTP调用
  2. 使用 for 循环和 switch 语句处理返回的数据
  3. 将其保存到范围

我想将其移至服务。到目前为止,我有这个:

angular.module('myApp.services', [])
.service('apiService', ['$http', 'webapiBase', function($http, webapiBase) {
  this.getData = function(){
    $http.get(webapiBase + '/api/getData').then(function(res){
      var obj = res.data;
      // Processing stuff
      return obj;
    }, function(err){
      return false;
    })
  }
}]);

在我的控制器中,当此服务返回其数据时,我需要运行回调,例如:

// In my Service:
this.getData = function(cb){
    $http.get(webapiBase + '/api/getData').then(function(res){
       var obj = res.data; 
       cb(obj);
    }, function(err){
       cb(false);
    })
  }
// In my controller
apiService.getData(function(data){
    $scope.data = data;
    // Do other stuff here
})   

但这感觉有点奇怪/非"棱角分明"。

有没有一种更"角度"的方式来实现这一目标,也许在使用$q时?

你只需要对你的服务做一个小的修改

  this.getData = function(){
    return $http.get(webapiBase + '/api/getData').then(function(res){
      // Processing stuff
      return object;
    }, function(err){
      return false;
    })
  }

直接返回$http.get的承诺对象。然后在您的控制器中

apiService.getData().then(function(data){
    $scope.data = data;
    // Do other stuff here
})

编辑

如果你真的不想重用$http创建的promise对象,你可以真正快速创建自己的。

this.getData = function() {
    var deferred = $q.defer();
    $http.get(webapiBase + '/api/getData').then(function(res){
      // Processing stuff
      deferred.resolve(object);
    }, function(err){
      deferred.reject('error');
    });
    return deferred.promise;
}
您可以使用

$q来实现所需的内容。

// Your service
angular.module('myApp.services', [])
.service('apiService', ['$http', 'webapiBase', function($http, webapiBase) {
  this.getData = function() {
    var deferred = $q.defer();
    $http.get(webapiBase + '/api/getData').then(
        function (res) {
            // Do something with res.data
            deferred.resolve(res.data);
        },
        function(res){
            deferred.reject();
        }
    );
    return deferred.promise;
  }
}]);

然后在控制器中使用$q承诺并对其进行响应:

// Your controller
apiService.getData().then(function(data) {
    $scope.data = data;
    // Do other stuff here
});

这就是角度方式,使用承诺与$q.