角js无限迭代误差

时间:2017-01-04 05:00:59

标签: angularjs

运行angularjs调用休息服务时遇到错误。详情如下。

这是我的app.js代码:

angular.module('myApp', []);

angular.module('myApp').factory('weatherService',function($http){
    return {
        getWeather:function(city,country){
            var query = 'city=' + city + '&country=' + country;
            return $http.get('http://api.openweathermap.org/data/2.5/weather',{
                params: {
                    q:query
                }
            }).then(function(response){
                return response.data.weather[0].description;
            });
        }
    }
});

angular.module('myApp').controller('WeatherController',
    function($scope,weatherService){
        $scope.getWeather=function(city,country){
            $scope.WeatherDescription = "Fetching...";
            weatherService.getWeather(city,country).then(function(data){
                $scope.weatherDescription = data;
            }, function(data){
                $scope.weatherDescription = "Could not obtain data";
            });
        }
});

html代码:

<html ng-app="myApp">
    <script src="../js/angular/angular.js" ></script>
    <script src="../js/app.js" ></script>
        <body ng-controller="WeatherController">
            {{getWeather('chicago','usa')}}
        </body>
</html>

我在页面中得到一个空白的回复。当我打开控制台时,我收到此错误:

Watchers fired in the last 5 iterations: []
http://errors.angularjs.org/1.3.13/$rootScope/infdig?p0=10&p1=%5B%5D
    at angular.js:63
    at Scope.$digest (angular.js:14281)
    at Scope.$apply (angular.js:14506)
    at done (angular.js:9659)
    at completeRequest (angular.js:9849)
    at XMLHttpRequest.requestLoaded (angular.js:9790)
(anonymous) @ angular.js:11607
(anonymous) @ angular.js:8557
$apply @ angular.js:14508
done @ angular.js:9659
completeRequest @ angular.js:9849
requestLoaded @ angular.js:9790
angular.js:63 Uncaught Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!

可能出现什么问题?有人可以帮忙吗?我顺便使用版本1.6.1

谢谢。

2 个答案:

答案 0 :(得分:1)

这与角度$digest周期如何工作以及如何评估表达式有关。

您的HTML中有一个表达式{{getWeather('chicago','usa')}}。每当发生$digest个循环时,将对该表达式求值,并调用该函数。

该函数设置值$scope.WeatherDescription = "Fetching...";,然后调用异步函数。然后$scope.WeatherDescription中的更改会导致新的$digest次迭代。新的$digest迭代遇到了表达式,并且再次触发了该函数。即使数据从promise中返回,它的将导致$scope上的属性发生更改,这将导致(另一个)$digest,导致(另一个) !)调用函数...这将基本上无限发生,这就是为什么角度在10个周期后自动抢占处理的原因。

有时可以在表达式中触发函数调用,但为了使其起作用,函数调用需要返回一个值,并且还需要不触发对另一个的更改与表达无关的$scope上的属性。

在您的情况下,您不希望使用$scope.WeatherDescription,而是希望return来自您服务的承诺。

答案 1 :(得分:0)

您可以通过选中$digest来检查$scope.$$phase是否正在进行中。

weatherService.getWeather(city,country).then(function(data){
              if(!$scope.$$phase) {
                $scope.weatherDescription = data;
              }
           }, function(data){
              if(!$scope.$$phase) {
                $scope.weatherDescription = "Could not obtain data";
              } 
         });