2

我有乘法函数,如count() getTotal(). 如果我的cart/object. 目前我在视图中使用它们,例如{{count()}}. 所以所有这些功能都在运行多次。我认为这些函数被称为多次,因为脏检查。它是否正确?

现在我阅读了有关该$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 的性能更好吗?

4

1 回答 1

3

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

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

现在,回答你的问题:

每次事件由 Angular 处理时,事件处理程序都可以修改范围内的任何内容。Angular 无法知道修改了什么。所以它必须调用,例如,getTotalItems()因为事件处理程序可能已经改变了一些东西,使得返回值getTotalItems()改变。

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

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

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

于 2016-04-01T20:35:38.483 回答