Angular 避免函数表达式 运行 相乘

Angular avoid function expression from running multiply times

我有像 count() getTotal() 这样的乘法函数。如果我的 cart/object 发生某些变化,所有这些计算函数都必须 运行。 目前我在像 {{count()}} 这样的视图中使用它们。所以所有这些函数都是运行宁。 我认为这些函数被称为 multiply times,因为脏检查。这是正确的吗?

现在我读到了 $watch 函数,由于性能问题,您应该尽量避免使用它。不管怎样,我想测试一下,$watched我的 cart。我发现它只记录一个 单次 所以 $watch 我的 cart 并调用那里的所有计算函数然后绑定会不会更快到计算结果?

我有点困惑,因为我认为它会有相同的行为。因为 $watch 也会经过摘要循环。

我知道已经有很多类似的问题,但是如果有人用不太难的英语直接为我的案例解释,会容易很多。

示例: 什么性能更好?为什么?两种变体都经过摘要循环吗?为什么变体 2 记录 10 次而变体 1 只记录 1 次?

变体 1

// bind these to scope and show like {{totalGross}}
cartService.totalGross = null;
cartService.totalNet = null;
cartService.totalItems = null;
// watch the cart here and update all variables
$rootScope.$watch(function () {
    return cartService.cart;
}, function(){
    cartService.totalGross = cartService.getCartTotalGross();
    cartService.totalNet = cartService.getCartTotalNet();
    cartService.totalItems = cartService.getTotalItems();
}, true);

变体 2

// bind these to scope and show like {{getCartTotalGross()}}
cartService.getCartTotalGross();
cartService.getCartTotalNet();
cartService.getTotalItems();

试着回答我自己的问题,虽然我不确定它是否正确。

变体 1 你还有 1 个观察者,但我们只观察值而不是函数,另外 1 个是因为我们用 $watch 手动观察购物车。但是观察者的计算量较小。

变体 2 我们正在观察函数返回的值,因此函数必须计算相同的值乘以多次, 更重。在每个摘要循环中 UI 得到更新

这是正确的吗?所以变体 1 的性能更好?

通常认为使用 $watch 不是(仅)因为它有性能问题,而是因为在大多数情况下有更好的选择(更清晰、更有效)。

例如,为了计算依赖于此值的某些内容,您可以在输入上使用 ng-change 并从那里。这样速度更快,意图更明确。

现在,回答你的问题:

每次 angular 处理事件时,事件处理程序都可以修改范围内的任何内容。 Angular 无法知道修改了什么。因此它必须调用,例如,getTotalItems(),因为事件处理程序可能更改了某些内容,导致 getTotalItems() 的返回值发生更改。

此外,更改任何被监视的值都会导致执行观察者函数,而这个观察者函数又可以更改其他值,其他值可以被其他观察者观察等等。所以angular 需要在一个循环中评估所有观察到的表达式,直到可以确定最后一次评估导致与前一次评估相同的结果。这就是所谓的摘要循环。

所以,简而言之,如果该函数只是 returns 一些简单的东西,比如数组的长度,或者几个值的总和,那么在视图中有 {{ getTotalItems() }} 并不是什么大问题.但是如果它计算生命的意义,那是一个非常糟糕的主意,你应该只在需要计算生命的意义时才计算生命的意义,并将结果存储在视图中显示的变量中。

你可以用观察者来做,但那应该是最后的手段。正如我已经说过的,通常有更好的选择。