在$watch函数(AngularJS)中调用$evalAsync时的无限循环
我正在关注Tero Parviainen的书“构建您自己的angularJS”,我发现理解他在谈论$evalAsync时介绍的一个概念有困难 在其中一个示例中,他声明了一个始终调用$evalAsync的观察者:在$watch函数(AngularJS)中调用$evalAsync时的无限循环,angularjs,scope,digest,Angularjs,Scope,Digest,我正在关注Tero Parviainen的书“构建您自己的angularJS”,我发现理解他在谈论$evalAsync时介绍的一个概念有困难 在其中一个示例中,他声明了一个始终调用$evalAsync的观察者: it('eventually halts $evalAsyncs added by watches', function() { scope.aValue = [1, 2, 3]; scope.$watch( function(scope) { scope.$
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);
};
如果对于循环中的每个迭代,如果从数组中转移一个异步任务,那么该循环如何永远运行?循环不应该因为$$asyncQueue被清空而停止吗
希望我说清楚了,谢谢大家 通过调用:
scope.$evalAsync(function(scope) { });
将新项目添加到asyncQueue
:
asyncQueue.push({scope: this, expression: expr, locals: locals});
因此,通过this.$$asyncQueue.shift()删除任务代码>我们称新的迭代为新的摘要周期
无论如何,watcher的正确实现是:
scope.aValue = [1, 2, 3];
scope.$watch(
function(scope) {
return scope.aValue;
},
function(newValue, oldValue, scope) { }
);
致电:
scope.$evalAsync(function(scope) { });
将新项目添加到asyncQueue
:
asyncQueue.push({scope: this, expression: expr, locals: locals});
因此,通过this.$$asyncQueue.shift()删除任务代码>我们称新的迭代为新的摘要周期
无论如何,watcher的正确实现是:
scope.aValue = [1, 2, 3];
scope.$watch(
function(scope) {
return scope.aValue;
},
function(newValue, oldValue, scope) { }
);
嘿,马克西姆!谢谢你的回答。据我所知,只触发了一个摘要周期,但正如您所说,在调用$evalAsync时,您向asyncQueue添加了一个新项。我不明白为什么这个过程会一次又一次地重复。我在摘要函数的开头调用了console.log,它只被调用一次。为什么使用$eval执行```函数(作用域){}``时会不断向$$asyncQueue添加一项?再次感谢您,很抱歉给您带来麻烦understanding@Riboher我不明白的是为什么这个过程会一次又一次地重复。
这就是我所说的,范围。$evalAsync
将新项添加到异步队列
并调用新的观察迭代器。新的迭代器再次调用scope.$evalAsync
,所以这个循环是无限的!谢谢你的回答。据我所知,只触发了一个摘要周期,但正如您所说,在调用$evalAsync时,您向asyncQueue添加了一个新项。我不明白为什么这个过程会一次又一次地重复。我在摘要函数的开头调用了console.log,它只被调用一次。为什么使用$eval执行```函数(作用域){}``时会不断向$$asyncQueue添加一项?再次感谢您,很抱歉给您带来麻烦understanding@Riboher我不明白的是为什么这个过程会一次又一次地重复。
这就是我所说的,范围。$evalAsync
将新项添加到异步队列
并调用新的观察迭代器。新的迭代器再次调用scope.$evalAsync
,所以这个循环是无限的