@@ -33,7 +33,9 @@ export class ConnectableObservable<T> extends Observable<T> {
33
33
connect ( ) : Subscription {
34
34
let connection = this . _connection ;
35
35
if ( ! connection ) {
36
- connection = this . source . subscribe ( new ConnectableSubscriber ( this . getSubject ( ) , this ) ) ;
36
+ connection = this . _connection = new Subscription ( ) ;
37
+ connection . add ( this . source
38
+ . subscribe ( new ConnectableSubscriber ( this . getSubject ( ) , this ) ) ) ;
37
39
if ( connection . isUnsubscribed ) {
38
40
this . _connection = null ;
39
41
connection = Subscription . EMPTY ;
@@ -66,9 +68,13 @@ class ConnectableSubscriber<T> extends SubjectSubscriber<T> {
66
68
const { connectable } = this ;
67
69
if ( connectable ) {
68
70
this . connectable = null ;
71
+ const connection = ( < any > connectable ) . _connection ;
69
72
( < any > connectable ) . _refCount = 0 ;
70
73
( < any > connectable ) . _subject = null ;
71
74
( < any > connectable ) . _connection = null ;
75
+ if ( connection ) {
76
+ connection . unsubscribe ( ) ;
77
+ }
72
78
}
73
79
}
74
80
}
@@ -122,10 +128,35 @@ class RefCountSubscriber<T> extends Subscriber<T> {
122
128
return ;
123
129
}
124
130
131
+ ///
132
+ // Compare the local RefCountSubscriber's connection Subscription to the
133
+ // connection Subscription on the shared ConnectableObservable. In cases
134
+ // where the ConnectableObservable source synchronously emits values, and
135
+ // the RefCountSubscriber's dowstream Observers synchronously unsubscribe,
136
+ // execution continues to here before the RefCountOperator has a chance to
137
+ // supply the RefCountSubscriber with the shared connection Subscription.
138
+ // For example:
139
+ // ```
140
+ // Observable.range(0, 10)
141
+ // .publish()
142
+ // .refCount()
143
+ // .take(5)
144
+ // .subscribe();
145
+ // ```
146
+ // In order to account for this case, RefCountSubscriber should only dispose
147
+ // the ConnectableObservable's shared connection Subscription if the
148
+ // connection Subscription exists, *and* either:
149
+ // a. RefCountSubscriber doesn't have a reference to the shared connection
150
+ // Subscription yet, or,
151
+ // b. RefCountSubscriber's connection Subscription reference is identical
152
+ // to the shared connection Subscription
153
+ ///
125
154
const { connection } = this ;
126
- if ( connection ) {
127
- this . connection = null ;
128
- connection . unsubscribe ( ) ;
155
+ const sharedConnection = ( < any > connectable ) . _connection ;
156
+ this . connection = null ;
157
+
158
+ if ( sharedConnection && ( ! connection || sharedConnection === connection ) ) {
159
+ sharedConnection . unsubscribe ( ) ;
129
160
}
130
161
}
131
162
}
0 commit comments