【问题标题】:Angular promises - cannot read property then of undefined角度承诺 - 无法读取未定义的属性
【发布时间】:2015-06-10 10:51:58
【问题描述】:

我试图在视图中显示承诺的结果,但我得到了这个异常。我在 Google / SO 上发现的其他这种异常情况是由我在代码中看不到的错误引起的。

我已经验证我正在使用 Promise,我正在解析传递给 $timeout 的函数内部的 Promise,我从函数 getData() 返回 Promise,而不是解析 Promise 的函数。

提前致谢。

查看者

<html ng-app="controller" ng-controller="MyController as controller">
<head>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.16/angular.min.js"></script>
  <script type="text/javascript" src="controller.js"></script>
  <script type="text/javascript" src="services.js"></script>
</head>
<body>
  {{data}}
</body>
</html>

控制器(controller.js)

   angular.module('controller', ['services'])
    .controller('MyController', ['MyService', function(MyService) {

      MyService.getData().then(function(data) {
        $scope.data = data;
      });
    }]);

服务(services.js)

angular.module('services', [])
.factory('MyService', function($q, $timeout){
  var getData = function getData() {

    var deferred = $q.defer;

    $timeout(function () {
      deferred.resolve('Foo');
    }, 5000);

    return deferred.promise;
  };

  return {
    getData: getData
  };
});

异常堆栈跟踪

TypeError: Cannot read property 'then' of undefined
    at new <anonymous> (controller.js:5)
    at Object.e [as invoke] (angular.js:4219)
    at $get.x.instance (angular.js:8525)
    at angular.js:7771
    at q (angular.js:334)
    at M (angular.js:7770)
    at g (angular.js:7149)
    at angular.js:7028
    at angular.js:1460

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    您没有正确获取延迟对象,而是deferred 变量保存了函数引用,您错过了延迟构造函数的调用。

    var deferred = $q.defer();
                            ^___Missing this
    

    还请注意,您可以按原样返回$timeout,因为它返回一个承诺。在您的实际情况下,如果您使用 $http,只需返回 $http 承诺,而不是使用 deferred pattern 创建冗余承诺对象。

    .factory('MyService', function($q, $timeout){
      var getData = function getData() {
    
        return $timeout(function () {
            return 'Foo' ;
        }, 5000);
      };
    
      return {
        getData: getData
      };
    

    【讨论】:

    • 谢谢。我正在实现一个我发现的例子,他们犯了同样的错误。
    • @AfterWorkGuinness 很容易错过。但是您始终可以通过调试/控制台日志记录进行交叉验证。
    猜你喜欢
    • 2019-03-10
    • 2021-02-27
    • 1970-01-01
    • 1970-01-01
    • 2017-12-22
    • 1970-01-01
    • 1970-01-01
    • 2019-04-23
    • 1970-01-01
    相关资源
    最近更新 更多