scope - Infinite loop when calling $evalAsync within a $watch function (AngularJS) -
i'm following along tero parviainen's book "build own angularjs" , i'm finding trouble understanding 1 of concepts introduces when talking $evalasync.
in 1 of examples declares watcher calls $evalasync:
it('eventually halts $evalasyncs added 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(); });
seeing example, expect digest cycle iterate twice through watchers until stopping. in implementation of scope, code runs until digest not dirty or there no more $evalasyncs in queue.
scope.prototype.$digest = function () { var ttl = 10; var dirty; this.$$lastdirtywatch = null; { 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); };
if each iteration in loop, 1 asynctask if shifted array, how comes that loop runs forever? shouldn't loop stop because $$asyncqueue gets emptied?
hope made myself clear , everyone!
by calling:
scope.$evalasync(function(scope) { });
you add new item asyncqueue
:
asyncqueue.push({scope: this, expression: expr, locals: locals});
so removing task this.$$asyncqueue.shift();
call new iteration a.e. new digest cycle.
anyways proper implementation of watcher is:
scope.avalue = [1, 2, 3]; scope.$watch( function(scope) { return scope.avalue; }, function(newvalue, oldvalue, scope) { } );
Comments
Post a Comment