我跟随Tero Parviainen的书"建立你自己的角度"在谈论$ evalAsync时,我很难理解他所介绍的一个概念。
在其中一个例子中,他声明了一个总是调用$ evalAsync的观察者:
it('eventually halts $evalAsyncs added by watches', function() {
scope.aValue = [1, 2, 3];
scope.$watch(
function(scope) {
scope.$evalAsync(function(scope) { });
return scope.aValue;
},
function(newValue, oldValue, scope) { }
);
expect(function() { scope.$digest(); }).toThrow();
});
看到这个例子,我希望摘要周期在观察者中迭代两次直到停止。在范围的实现中,代码一直运行,直到摘要不脏或队列中没有$ evalAsyncs。
Scope.prototype.$digest = function () {
var ttl = 10;
var dirty;
this.$$lastDirtyWatch = null;
do {
while (this.$$asyncQueue.length) {
var asyncTask = this.$$asyncQueue.shift();
asyncTask.scope.$eval(asyncTask.expression);
}
dirty = this.$$digestOnce();
if ((dirty || this.$$asyncQueue.length) && !(ttl--)) {
throw '10 digest iterations reached';
}
} while (dirty || this.$$asyncQueue.length);
};
如果对于循环中的每次迭代,如果一个asyncTask从数组移位,那么该循环如何永远运行?因为$$ asyncQueue被清空了,所以循环不应该停止吗?
希望我明确表达并感谢大家!
答案 0 :(得分:0)
致电:
scope.$evalAsync(function(scope) { });
您将新项目添加到asyncQueue
:
asyncQueue.push({scope: this, expression: expr, locals: locals});
所以通过this.$$asyncQueue.shift();
删除任务我们调用新的迭代a.e.新的消化周期。
无论如何,观察者的正确实施是:
scope.aValue = [1, 2, 3];
scope.$watch(
function(scope) {
return scope.aValue;
},
function(newValue, oldValue, scope) { }
);