@@ -195,15 +195,15 @@ export class Batch {
195195 // if we didn't start any new async work, and no async work
196196 // is outstanding from a previous flush, commit
197197 if ( this . #async_effects. length === 0 && this . #pending === 0 ) {
198+ this . #commit( ) ;
199+
198200 var render_effects = this . #render_effects;
199201 var effects = this . #effects;
200202
201203 this . #render_effects = [ ] ;
202204 this . #effects = [ ] ;
203205 this . #block_effects = [ ] ;
204206
205- this . #commit( ) ;
206-
207207 flush_queued_effects ( render_effects ) ;
208208 flush_queued_effects ( effects ) ;
209209
@@ -544,60 +544,59 @@ function flush_queued_effects(effects) {
544544 var length = effects . length ;
545545 if ( length === 0 ) return ;
546546
547- for ( var i = 0 ; i < length ; i ++ ) {
548- var effect = effects [ i ] ;
549-
550- if ( ( effect . f & ( DESTROYED | INERT ) ) === 0 ) {
551- if ( is_dirty ( effect ) ) {
552- var wv = write_version ;
553- var current_size = /** @type { Batch } */ ( current_batch ) . current . size ;
554-
555- update_effect ( effect ) ;
556-
557- // Effects with no dependencies or teardown do not get added to the effect tree.
558- // Deferred effects (e.g. `$effect(...)`) _are_ added to the tree because we
559- // don't know if we need to keep them until they are executed. Doing the check
560- // here (rather than in `update_effect`) allows us to skip the work for
561- // immediate effects.
562- if ( effect . deps === null && effect . first === null && effect . nodes_start === null ) {
563- // if there's no teardown or abort controller we completely unlink
564- // the effect from the graph
565- if ( effect . teardown === null && effect . ac === null ) {
566- // remove this effect from the graph
567- unlink_effect ( effect ) ;
568- } else {
569- // keep the effect in the graph, but free up some memory
570- effect . fn = null ;
571- }
547+ var i = 0 ;
548+
549+ while ( i < length ) {
550+ var effect = effects [ i ++ ] ;
551+
552+ if ( ( effect . f & ( DESTROYED | INERT ) ) === 0 && is_dirty ( effect ) ) {
553+ var wv = write_version ;
554+ var current_size = /** @type { Batch } */ ( current_batch ) . current . size ;
555+
556+ update_effect ( effect ) ;
557+
558+ // Effects with no dependencies or teardown do not get added to the effect tree.
559+ // Deferred effects (e.g. `$effect(...)`) _are_ added to the tree because we
560+ // don't know if we need to keep them until they are executed. Doing the check
561+ // here (rather than in `update_effect`) allows us to skip the work for
562+ // immediate effects.
563+ if ( effect . deps === null && effect . first === null && effect . nodes_start === null ) {
564+ // if there's no teardown or abort controller we completely unlink
565+ // the effect from the graph
566+ if ( effect . teardown === null && effect . ac === null ) {
567+ // remove this effect from the graph
568+ unlink_effect ( effect ) ;
569+ } else {
570+ // keep the effect in the graph, but free up some memory
571+ effect . fn = null ;
572572 }
573+ }
573574
574- // if state is written in a user effect, abort and re-schedule, lest we run
575- // effects that should be removed as a result of the state change
576- if ( write_version > wv && ( effect . f & USER_EFFECT ) !== 0 ) {
577- // Work needs to happen in a separate batch, else prior sources would be mixed with
578- // newly updated sources, which could lead to infinite loops when effects run over and over again.
579- // We need to bring over the just written sources though to correctly mark the right reactions as dirty.
580- var old_batch = /** @type {Batch } */ ( current_batch ) ;
581- batches . delete ( old_batch ) ;
582- current_batch = null ;
583- var new_batch = Batch . ensure ( ! flushing_sync ) ;
584- var current_idx = 0 ;
585- // We're taking advantage of the spec here which says that entries in a Map are traversed by insertion order
586- for ( const source of old_batch . current ) {
587- if ( current_idx >= current_size ) {
588- new_batch . capture ( source [ 0 ] , source [ 1 ] ) ;
589- }
590- current_idx ++ ;
575+ // if state is written in a user effect, abort and re-schedule, lest we run
576+ // effects that should be removed as a result of the state change
577+ if ( write_version > wv && ( effect . f & USER_EFFECT ) !== 0 ) {
578+ // Work needs to happen in a separate batch, else prior sources would be mixed with
579+ // newly updated sources, which could lead to infinite loops when effects run over and over again.
580+ // We need to bring over the just written sources though to correctly mark the right reactions as dirty.
581+ var old_batch = /** @type {Batch } */ ( current_batch ) ;
582+ batches . delete ( old_batch ) ;
583+ current_batch = null ;
584+ var new_batch = Batch . ensure ( ! flushing_sync ) ;
585+ var current_idx = 0 ;
586+ // We're taking advantage of the spec here which says that entries in a Map are traversed by insertion order
587+ for ( const source of old_batch . current ) {
588+ if ( current_idx >= current_size ) {
589+ new_batch . capture ( source [ 0 ] , source [ 1 ] ) ;
591590 }
592- i ++ ;
593- break ;
591+ current_idx ++ ;
594592 }
593+ break ;
595594 }
596595 }
597596 }
598597
599- for ( ; i < length ; i += 1 ) {
600- schedule_effect ( effects [ i ] ) ;
598+ while ( i < length ) {
599+ schedule_effect ( effects [ i ++ ] ) ;
601600 }
602601}
603602
0 commit comments