Angularjs $ http承诺推迟

时间:2015-10-10 01:45:49

标签: angularjs angular-http

我正在使用 1.4.7中的$http

我需要将控制器与任何$http请求分开。所以我创建了如下服务:

app.service('MyService', function($http, $q, $rootScope) {

  this.getcustomers = function() {
    var deferred = $q.defer();
    $http({
      method: 'GET',
      url: 'http://call/to/rest/api'
    }).then(function successCallback(response) {
      deferred.resolve(response.data);
    }, function errorCallback(response) {
      deferred.reject(error);
    });
    return deferred.promise;
  };

});

然后在我的控制器中,我按如下方式调用该服务:

app.controller('registerationCtrl', ['$scope', '$http', 'MyService', '$location', function($scope, $http, MyService, $location) {
  $scope.custlst = [];

  $scope.getcustomers = function() {

    var x = MyService.getcustomers().then(function(data) {
      $scope.custlst = data;
    }, function(err) {
      alert(err);
    });

  }


}]);

现在,以上操作无效,它现在定义了ReferenceError错误,并指向服务中的errorCallback函数。

问题1:脚本有什么问题? 问题2:使用$q是否重要?请记住,服务器可能很慢。

感谢。

3 个答案:

答案 0 :(得分:2)

实际上,您不需要使用$q来创建承诺。 $http已经为你做了,所以你可以这样做:

app.service('MyService', function($http) {
  this.getcustomers = function() {
    return $http.get({
      method: 'GET',
      url: 'http://call/to/rest/api'
    });
  };
});

然后,您可以轻松地将MyService.getcustomers.then()链接起来,并按照以下方式处理响应:

MyService.getcustomers.then(
  function(data) {
    //do something with data
  },
  function(error) {
    //do something with error
  }
);

我认为你应该看一下this post我想更好地理解承诺的运作方式和行为。

编辑:更新已弃用的$http来电。

答案 1 :(得分:1)

嗯,在AngularJS文档中:https://docs.angularjs.org/api/ng/service/$http

  

弃用通知 $ http旧版承诺方法成功与错误已被弃用。请改用标准方法。如果   $ httpProvider.useLegacyPromiseExtensions设置为false然后这些   方法将抛出$ http / legacy错误。

您不需要使用$ q承诺。

当您使用GET请求时,您可以使用快捷方式执行GET请求:$http.get();

所以,你可以尝试这样的事情:

MyService服务:只需要$http服务。

app.service("MyService", ["$http", function ($http) {
    this.getcustomers = function () {
        return $http.get("http://call/to/rest/api");
    };
}]);

上述服务允许您在任何控制器中使用该服务。因此,任何控制器都可以使用相同的数据执行其他操作。

registerationCtrl controller:您需要$scopeMyServicelocation服务。

    app.controller("registerationCtrl", ["$scope", "MyService", "$location", function ($scope, MyService, location) {
        $scope.custlst = [];

        $scope.getcustomers = function () {
            MyService.getcustomers().then(function (response) {
                $scope.custlst = response.data;
            }, function (err) {
                alert(err);
            });
        };
    }]);
}]);

答案 2 :(得分:1)

正如我在评论中提到的,您看到的错误是由于error变量未在errorCallback函数中声明。

至于$q - 不需要使用它,虽然你实现的方式仍然可行。为了使它更简单并遵循promises的意图(即它们允许异步代码镜像同步代码的代码组合),最好返回$http(或{{1}的原始承诺。 }):

$http().then()

然后,客户端可以按预期使用:

this.getcustomers = function() {
  return $http({
      method: 'GET',
      url: 'http://call/to/rest/api'
    })
    // pre-process the HTTP response and return the data
    .then(function(response) {
      return response.data;
    })
    // If needed, create a custom error to hide HTTP details from caller
    // otherwise, don't include .catch - the original error will "bubble up"
    .catch(function(error) {
      return $q.reject({
        msg: "something broke"
      });
    });
};