2

This is a bit of a theoretical question, but important in my understanding how the Digest Loop in Angular 1.x works.

I understand why the Digest loop would usually run twice. Once for detecting changes and another time to make sure no watched expression is 'dirty'.

I can also easily concoct an example that puts the loop into an infinite cycle, thus more than 10 times and causing it to throw an exception.

However, what circumstance (with an example) would there be when the loop runs more than twice but less than 10 times? It almost seems like there is logic somewhere inside the loop to do some magic rechecking of expressions or queuing up expressions or something that causes it to always run only 2 times. Once to update all the changed values and once to verify that nothing has changed.

What set of watchers would cause this to execute 3 times, for example.

I keep trying to come up with an example that has a custom watcher do some side effect on some $scope.prop that's watched as well, but the digest loop does not run more than twice.

In other words, if the watcher does a side effect in a limited fashion like this:

if (some limited condition) change another watched $scope.property 

Then, the digest loop runs only 2 times.

If the watcher does a side effect without any limits on the condition for when that side effect gets triggered, it comes an infinite loop (understandably). For example:

$scope.someProp++ 

Is there an example of how you can force the digest loop to run 3 times? It's almost as if it's somehow making sure all the changes occur in the first loop, making the 2nd loop there to check that all props have dirty=false, so it can then stop.

Isn't the 2nd loop to make SURE that nothing has changed as a result of the first loop? If so, it must be possible to trigger the condition where something DID change as part of the first loop but is not detected until the 2nd loop, making loop #3 the final 'clean' one, not just stop at 2nd loop.

Just trying to understand how this whole digest thing works.

Thanks!

1
  • Consider a controller and 2 variables: a and b. The controller specifies the rule: $scope.$watch('a', function(newval) { b = newval + 1 }). Also a and b are watched by the view and a button defines ng-click="a = 10". The user presses the button, a becomes 10 and a digest is run (1). Angular notices that the watched value changed, and fires the function; b becomes 11 and a second digest is run (2). In the second digest, Angular notices that b has changed and invokes the change listener from the view. Then runs a final digest (3), notices that nothing changed and stops. Commented Jul 22, 2016 at 19:06

1 Answer 1

1

A little bit artificial, but hey ;) Euclidean algorithm implemented using $scope.$watch. As you can sometimes there is stop condition, like in this case. When b === 0 then digest cycle stops.

So I guess, any similar case, when change values in scope based on some condition would fire more than 2 but not infinitely.

angular.module('app', []); angular .module('app') .controller('Example', function ($scope) { $scope.a = 45; $scope.b = 375; $scope.$watch('a', function () { console.log($scope.a, $scope.b); if ($scope.b !== 0) { const temp = $scope.b; $scope.b = $scope.a % $scope.b; $scope.a = temp; } }); });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.js"></script> <div ng-app="app" ng-controller="Example"> {{a}} </div>

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.