@@ -730,98 +730,100 @@ function $RootScopeProvider() {
730730 logIdx , logMsg , asyncTask ;
731731
732732 beginPhase ( '$digest' ) ;
733- // Check for changes to browser url that happened in sync before the call to $digest
734- $browser . $$checkUrlChange ( ) ;
735-
736- if ( this === $rootScope && applyAsyncId !== null ) {
737- // If this is the root scope, and $applyAsync has scheduled a deferred $apply(), then
738- // cancel the scheduled $apply and flush the queue of expressions to be evaluated.
739- $browser . defer . cancel ( applyAsyncId ) ;
740- flushApplyAsync ( ) ;
741- }
733+ try {
734+ // Check for changes to browser url that happened in sync before the call to $digest
735+ $browser . $$checkUrlChange ( ) ;
736+
737+ if ( this === $rootScope && applyAsyncId !== null ) {
738+ // If this is the root scope, and $applyAsync has scheduled a deferred $apply(), then
739+ // cancel the scheduled $apply and flush the queue of expressions to be evaluated.
740+ $browser . defer . cancel ( applyAsyncId ) ;
741+ flushApplyAsync ( ) ;
742+ }
742743
743- lastDirtyWatch = null ;
744+ lastDirtyWatch = null ;
744745
745- do { // "while dirty" loop
746- dirty = false ;
747- current = target ;
746+ do { // "while dirty" loop
747+ dirty = false ;
748+ current = target ;
748749
749- while ( asyncQueue . length ) {
750- try {
751- asyncTask = asyncQueue . shift ( ) ;
752- asyncTask . scope . $eval ( asyncTask . expression , asyncTask . locals ) ;
753- } catch ( e ) {
754- $exceptionHandler ( e ) ;
750+ while ( asyncQueue . length ) {
751+ try {
752+ asyncTask = asyncQueue . shift ( ) ;
753+ asyncTask . scope . $eval ( asyncTask . expression , asyncTask . locals ) ;
754+ } catch ( e ) {
755+ $exceptionHandler ( e ) ;
756+ }
757+ lastDirtyWatch = null ;
755758 }
756- lastDirtyWatch = null ;
757- }
758759
759- traverseScopesLoop:
760- do { // "traverse the scopes" loop
761- if ( ( watchers = current . $$watchers ) ) {
762- // process our watches
763- length = watchers . length ;
764- while ( length -- ) {
765- try {
766- watch = watchers [ length ] ;
767- // Most common watches are on primitives, in which case we can short
768- // circuit it with === operator, only when === fails do we use .equals
769- if ( watch ) {
770- if ( ( value = watch . get ( current ) ) !== ( last = watch . last ) &&
771- ! ( watch . eq
772- ? equals ( value , last )
773- : ( typeof value === 'number' && typeof last === 'number'
774- && isNaN ( value ) && isNaN ( last ) ) ) ) {
775- dirty = true ;
776- lastDirtyWatch = watch ;
777- watch . last = watch . eq ? copy ( value , null ) : value ;
778- watch . fn ( value , ( ( last === initWatchVal ) ? value : last ) , current ) ;
779- if ( ttl < 5 ) {
780- logIdx = 4 - ttl ;
781- if ( ! watchLog [ logIdx ] ) watchLog [ logIdx ] = [ ] ;
782- watchLog [ logIdx ] . push ( {
783- msg : isFunction ( watch . exp ) ? 'fn: ' + ( watch . exp . name || watch . exp . toString ( ) ) : watch . exp ,
784- newVal : value ,
785- oldVal : last
786- } ) ;
760+ traverseScopesLoop:
761+ do { // "traverse the scopes" loop
762+ if ( ( watchers = current . $$watchers ) ) {
763+ // process our watches
764+ length = watchers . length ;
765+ while ( length -- ) {
766+ try {
767+ watch = watchers [ length ] ;
768+ // Most common watches are on primitives, in which case we can short
769+ // circuit it with === operator, only when === fails do we use .equals
770+ if ( watch ) {
771+ if ( ( value = watch . get ( current ) ) !== ( last = watch . last ) &&
772+ ! ( watch . eq
773+ ? equals ( value , last )
774+ : ( typeof value === 'number' && typeof last === 'number'
775+ && isNaN ( value ) && isNaN ( last ) ) ) ) {
776+ dirty = true ;
777+ lastDirtyWatch = watch ;
778+ watch . last = watch . eq ? copy ( value , null ) : value ;
779+ watch . fn ( value , ( ( last === initWatchVal ) ? value : last ) , current ) ;
780+ if ( ttl < 5 ) {
781+ logIdx = 4 - ttl ;
782+ if ( ! watchLog [ logIdx ] ) watchLog [ logIdx ] = [ ] ;
783+ watchLog [ logIdx ] . push ( {
784+ msg : isFunction ( watch . exp ) ? 'fn: ' + ( watch . exp . name || watch . exp . toString ( ) ) : watch . exp ,
785+ newVal : value ,
786+ oldVal : last
787+ } ) ;
788+ }
789+ } else if ( watch === lastDirtyWatch ) {
790+ // If the most recently dirty watcher is now clean, short circuit since the remaining watchers
791+ // have already been tested.
792+ dirty = false ;
793+ break traverseScopesLoop;
787794 }
788- } else if ( watch === lastDirtyWatch ) {
789- // If the most recently dirty watcher is now clean, short circuit since the remaining watchers
790- // have already been tested.
791- dirty = false ;
792- break traverseScopesLoop;
793795 }
796+ } catch ( e ) {
797+ $exceptionHandler ( e ) ;
794798 }
795- } catch ( e ) {
796- $exceptionHandler ( e ) ;
797799 }
798800 }
799- }
800801
801- // Insanity Warning: scope depth-first traversal
802- // yes, this code is a bit crazy, but it works and we have tests to prove it!
803- // this piece should be kept in sync with the traversal in $broadcast
804- if ( ! ( next = ( ( current . $$watchersCount && current . $$childHead ) ||
805- ( current !== target && current . $$nextSibling ) ) ) ) {
806- while ( current !== target && ! ( next = current . $$nextSibling ) ) {
807- current = current . $parent ;
802+ // Insanity Warning: scope depth-first traversal
803+ // yes, this code is a bit crazy, but it works and we have tests to prove it!
804+ // this piece should be kept in sync with the traversal in $broadcast
805+ if ( ! ( next = ( ( current . $$watchersCount && current . $$childHead ) ||
806+ ( current !== target && current . $$nextSibling ) ) ) ) {
807+ while ( current !== target && ! ( next = current . $$nextSibling ) ) {
808+ current = current . $parent ;
809+ }
808810 }
809- }
810- } while ( ( current = next ) ) ;
811+ } while ( ( current = next ) ) ;
811812
812- // `break traverseScopesLoop;` takes us to here
813+ // `break traverseScopesLoop;` takes us to here
813814
814- if ( ( dirty || asyncQueue . length ) && ! ( ttl -- ) ) {
815- clearPhase ( ) ;
816- throw $rootScopeMinErr ( 'infdig' ,
817- '{0} $digest() iterations reached. Aborting!\n' +
818- 'Watchers fired in the last 5 iterations: {1}' ,
819- TTL , watchLog ) ;
820- }
821-
822- } while ( dirty || asyncQueue . length ) ;
815+ if ( ( dirty || asyncQueue . length ) && ! ( ttl -- ) ) {
816+ clearPhase ( ) ;
817+ throw $rootScopeMinErr ( 'infdig' ,
818+ '{0} $digest() iterations reached. Aborting!\n' +
819+ 'Watchers fired in the last 5 iterations: {1}' ,
820+ TTL , watchLog ) ;
821+ }
823822
824- clearPhase ( ) ;
823+ } while ( dirty || asyncQueue . length ) ;
824+ } finally {
825+ clearPhase ( ) ;
826+ }
825827
826828 while ( postDigestQueue . length ) {
827829 try {
0 commit comments