32

我有以下 angularjs 代码:

$scope.clients = commonFactory.getData(clientFactory.getClients());
if ($scope.clients.length > 0) {
    $scope.sampleForm.ClientId = $scope.clients[0].ClientId;
}

而commonFactory中的getData函数:

factory.getData = function (method) {
    method.then(function (response) {
        return response.data;
    }, function (error) {
        $rootScope.alerts.push({ type: 'error', msg: error.data.ExceptionMessage });
    });
};

问题是 $scope.clients.length 由于异步调用而在命中该行时未定义。

有没有办法在我知道 $scope.clients 已分配之前不进行长度检查?我看过这样的东西:

$scope.clients = commonFactory.getData(clientFactory.getClients()).then(function () {
    if ($scope.clients.length > 0) {
        $scope.sampleForm.ClientId = $scope.clients[0].ClientId;
    }
});

试图链接我的then承诺,但没有骰子......这里的目标是使用 getData 方法来避免一堆样板代码来捕获错误......也许我正在处理这个错误?

4

1 回答 1

34

这是 promises 的最基本情况。您只需要var deferred = $q.defer()在开始异步操作时做出承诺,deferred.resolve(result)在异步操作完成时解决承诺,然后deferred.promise在您的函数中返回。Angular 的异步方法在内部执行此操作并已返回 Promise,因此您可以只返回相同的 Promise,而不用创建新的 Promise $q.defer()。您可以将 a 附加.then到任何返回承诺的内容。此外,如果您从函数返回一个值then,该值将被包装在一个 Promise 中,以便then链可以继续

angular.module('myApp', [])

.factory('myService', function($q, $timeout, $http) {
  return {
    myMethod: function() {
      // return the same promise that $http.get returns
      return $http.get('some/url');
    }
  };
})

.controller('myCtrl', function($scope, myService) {
  myService.myMethod().then(function(resp) {
    $scope.result = resp.data;
  });
})

这里的链接更有趣:

.factory('myService', function($q, $timeout, $http) {
  return {
    myMethod: function() {
      // return the same promise that $http.get returns
      return $http.get('some/url').then(function() {
        return 'abc';
      });
    }
  };
})

.controller('myCtrl', function($scope, myService) {
  myService.myMethod().then(function(result) {
    console.log(result); // 'abc'
    return someOtherAsyncFunc(); // for example, say this returns '123'
  }).then(function(result) {
    console.log(result); // '123'
  });
})
于 2013-09-11T23:29:15.617 回答