消除根作用域摘要调用的抖动

Debouncing root scope digest invocations

如果我连续调用 $scope.$apply() 十次,我假设将出现十个根作用域摘要。

我们是否可以说,如果对 $scope.$apply() 的调用进行了去抖动,以便尾随调用始终完成,那么应用程序的最终状态将与去抖动未生效时的状态相同?

假设前一个摘要刚刚完成,我们能说说连续根作用域摘要的持续时间吗?

编辑:

我想澄清一下我提问的目的。

假设我有一个控制器 MyController,为指令的每个实例实例化了一个实例 MyDirective

这些控制器实例侦听事件 my-event 并在每次引发 my-event 时触发根范围摘要。

MyDirective 的 10 个实例通过 ng-repeat.

渲染到 UI

另一个组件引发事件 my-event。十个 MyController 个实例中的每一个都会触发根范围摘要。

如果我们把这种事态的理智放在一边,我的问题是:如果我对 MyController 进行的根范围摘要尝试进行反跳,并确保始终调用尾随尝试, 是否保持了程序的正确性?

var service = require('my-service');

function MyController($scope) {
  this._$scope = $scope;
  myService.on('my-event', this.triggerRootScopeDigest.bind(this));
}

MyController.prototype.triggerRootScopeDigest = function() {
  this._$scope.apply();
}

编辑后的问题仍然指向 $applyAsync$evalAsync 作为您的解决方案。

这是一个 fiddle 比较 $apply()$applyAsync() 的例子: http://jsfiddle.net/635pvkkt/

您会注意到通过 ngRepeat 添加了 10 个项目,每个项目观看一个 doApply 事件和一个 doApplyAsync 事件,以触发相应的功能。

当您单击广播 doApply 的按钮时,它会触发 10 个 $digest 调用,每个调用都执行指令工作(在本例中,很简单 console.log)。

然而,doApplyAsync 广播导致所有 10 个指令在单个 $digest.

中完成它们的工作

当然,去抖回调也可以。您可以将每个指令传递给附加到父控制器作用域的去抖动函数的引用。如果该去抖功能正常工作并且具有足够长的去抖时间,则它只会应用一次。在某些情况下这是首选,但最初的问题感觉很简单(假设触发 $digest 是事件的主要目标)用 $apply 代替 $applyAsync(或 $evalAsync , 取决于语义)似乎更合适。

编辑: 虽然结果完全相同,但这个 fiddle 更准确,因为它直接触发元素上的真实 DOM 事件:http://jsfiddle.net/uh9wxxho/