Angular避免函数表达式运行乘法乘以

时间:2016-04-01 18:07:26

标签: angularjs performance angular-digest

我有多个函数,例如count() getTotal()。如果某些内容发生变化cart/object,则必须运行所有这些计算函数。 目前我在{{count()}}这样的视图中使用它们。所以这些功能都在运行倍增。 我认为这些函数被称为乘法次数,因为脏检查。这是对的吗?

现在我读到了$watch函数,你应该尽量避免它,因为性能问题。无论如何,我想测试它,$watched我的cart。我发现它只记录单次所以$watch我的cart并不会更快,并调用那里的所有计算函数然后只是绑定到结果计算?

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

我知道已经有很多类似的问题,但是如果有人用一个不那么辛苦的英语直接解释我的情况,会让它变得容易多了。

示例: 有什么更好的表现?为什么?这两种变体都经历了摘要周期吗?为什么Variant 2会记录10次而Variant 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对性能有好处吗?

1 个答案:

答案 0 :(得分:3)

通常认为使用$ watch(仅)是不好的做法,因为它有性能问题,但是因为大多数时候都有更好的选择(更清晰,更有效)。

例如,不是观察用户在输入中输入内容时更改的模型值,而是为了计算依赖于此值的内容,您可以对输入使用ng-change并从那里调用计算。这样更快,意图更清晰。

现在,回答你的问题:

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

此外,更改所观察的任何值都会导致执行观察程序功能,并且此观察程序功能可以反过来更改其他观察者可以观看的其他值等。因此角度需要评估所有循环中观察到的表达式,直到可以确定最后一次评估导致与前一次评估相同的结果。这就是所谓的摘要循环。

因此,简而言之,如果该函数只返回一些简单的函数(例如数组的长度或几个值的总和),那么在视图中使用{{ getTotalItems() }}并不是什么大问题。但是如果它计算了生命的意义,那么它是一个非常糟糕的主意,你应该只在需要计算时计算生命的意义,并将结果存储在视图中显示的变量中。 / p>

你可以用观察者做到这一点,但这应该是最后的选择。正如我已经说过的,通常有更好的选择。