如何强制 Angular 1.x 摘要循环到 运行 3 次

How to force Angular 1.x Digest loop to run 3 times

这是一个有点理论性的问题,但对我理解 Angular 1.x 中摘要循环的工作原理很重要。

我理解为什么摘要循环通常会 运行 两次。一次用于检测变化,另一次用于确保没有观察到的表达式是 'dirty'.

我也可以很容易地编造一个例子,让循环进入无限循环,因此超过 10 次并导致它抛出异常。

但是,循环运行超过2次小于10次会是什么情况(举例)?似乎循环内部某处有逻辑来对表达式进行一些神奇的重新检查或对表达式进行排队或导致它总是 运行 只有 2 次。一次更新所有更改的值,一次验证没有任何更改。

例如,什么样的观察者集合会导致它执行 3 次。

我一直试图想出一个例子,其中有一个自定义观察器对一些也被观察到的 $scope.prop 产生一些副作用,但摘要循环不会 运行 超过两次.

换句话说,如果观察者像这样以有限的方式产生副作用:

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

然后,摘要循环 运行s 仅 2 次。

如果观察者对副作用触发的条件没有任何限制,就会出现无限循环(可以理解)。例如:

$scope.someProp++

是否有示例说明如何强制摘要循环 运行 3 次?这几乎就好像它以某种方式确保所有更改都发生在第一个循环中,使第二个循环在那里检查所有道具是否有 dirty=false,这样它就可以停止了。

第二个循环不是要确保第一个循环的结果没有任何改变吗?如果是这样,则必须有可能触发这样的条件,即某些 DID 在第一个循环中发生了变化,但直到第二个循环才被检测到,从而使循环 #3 成为最终的 'clean' 循环,而不仅仅是在第二个循环中停止。

只是想了解整个摘要的工作原理。

谢谢!

有点做作,但是嘿 ;) 使用 $scope.$watch 实现的欧几里得算法。正如您有时可以有停止条件,就像在这种情况下。当 b === 0 时,摘要循环停止。

所以我想,任何类似的情况下,当基于某些条件更改范围内的值时会触发超过 2 个但不是无限次。

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>