@@ -219,18 +219,21 @@ Signal.prototype._subscribe = function (node) {
219
219
} ;
220
220
221
221
Signal . prototype . _unsubscribe = function ( node ) {
222
- const prev = node . _prevTarget ;
223
- const next = node . _nextTarget ;
224
- if ( prev !== undefined ) {
225
- prev . _nextTarget = next ;
226
- node . _prevTarget = undefined ;
227
- }
228
- if ( next !== undefined ) {
229
- next . _prevTarget = prev ;
230
- node . _nextTarget = undefined ;
231
- }
232
- if ( node === this . _targets ) {
233
- this . _targets = next ;
222
+ // Only run the unsubscribe step if the signal has any subscribers to begin with.
223
+ if ( this . _targets !== undefined ) {
224
+ const prev = node . _prevTarget ;
225
+ const next = node . _nextTarget ;
226
+ if ( prev !== undefined ) {
227
+ prev . _nextTarget = next ;
228
+ node . _prevTarget = undefined ;
229
+ }
230
+ if ( next !== undefined ) {
231
+ next . _prevTarget = prev ;
232
+ node . _nextTarget = undefined ;
233
+ }
234
+ if ( node === this . _targets ) {
235
+ this . _targets = next ;
236
+ }
234
237
}
235
238
} ;
236
239
@@ -464,18 +467,22 @@ Computed.prototype._subscribe = function (node) {
464
467
} ;
465
468
466
469
Computed . prototype . _unsubscribe = function ( node ) {
467
- Signal . prototype . _unsubscribe . call ( this , node ) ;
468
-
469
- // Computed signal unsubscribes from its dependencies from it loses its last subscriber.
470
- if ( this . _targets === undefined ) {
471
- this . _flags &= ~ TRACKING ;
472
-
473
- for (
474
- let node = this . _sources ;
475
- node !== undefined ;
476
- node = node . _nextSource
477
- ) {
478
- node . _source . _unsubscribe ( node ) ;
470
+ // Only run the unsubscribe step if the computed signal has any subscribers.
471
+ if ( this . _targets !== undefined ) {
472
+ Signal . prototype . _unsubscribe . call ( this , node ) ;
473
+
474
+ // Computed signal unsubscribes from its dependencies when it loses its last subscriber.
475
+ // This makes it possible for unreferences subgraphs of computed signals to get garbage collected.
476
+ if ( this . _targets === undefined ) {
477
+ this . _flags &= ~ TRACKING ;
478
+
479
+ for (
480
+ let node = this . _sources ;
481
+ node !== undefined ;
482
+ node = node . _nextSource
483
+ ) {
484
+ node . _source . _unsubscribe ( node ) ;
485
+ }
479
486
}
480
487
}
481
488
} ;
0 commit comments