@@ -9,9 +9,15 @@ export class Subscriber<T> extends Subscription implements Observer<T> {
9
9
static create < T > ( next ?: ( x ?: T ) => void ,
10
10
error ?: ( e ?: any ) => void ,
11
11
complete ?: ( ) => void ) : Subscriber < T > {
12
- return new Subscriber ( next , error , complete ) ;
12
+ const subscriber = new Subscriber ( next , error , complete ) ;
13
+ subscriber . syncErrorThrowable = false ;
14
+ return subscriber ;
13
15
}
14
16
17
+ public syncErrorValue : any = null ;
18
+ public syncErrorThrown : boolean = false ;
19
+ public syncErrorThrowable : boolean = false ;
20
+
15
21
protected isStopped : boolean = false ;
16
22
protected destination : Observer < any > ;
17
23
@@ -33,11 +39,13 @@ export class Subscriber<T> extends Subscription implements Observer<T> {
33
39
if ( destinationOrNext instanceof Subscriber ) {
34
40
this . destination = ( < Observer < any > > destinationOrNext ) ;
35
41
} else {
42
+ this . syncErrorThrowable = true ;
36
43
this . destination = new SafeSubscriber < T > ( this , < Observer < any > > destinationOrNext ) ;
37
44
}
38
45
break ;
39
46
}
40
47
default :
48
+ this . syncErrorThrowable = true ;
41
49
this . destination = new SafeSubscriber < T > ( this , < ( ( value : T ) => void ) > destinationOrNext , error , complete ) ;
42
50
break ;
43
51
}
@@ -120,41 +128,78 @@ class SafeSubscriber<T> extends Subscriber<T> {
120
128
121
129
next ( value ?: T ) : void {
122
130
if ( ! this . isStopped && this . _next ) {
123
- this . __tryOrUnsub ( this . _next , value ) ;
124
- }
125
- }
126
-
127
- __tryOrUnsub ( fn : Function , value ?: any ) : void {
128
- try {
129
- fn . call ( this . _context , value ) ;
130
- } catch ( err ) {
131
- this . unsubscribe ( ) ;
132
- throw err ;
131
+ const { _parent } = this ;
132
+ if ( ! _parent . syncErrorThrowable ) {
133
+ this . __tryOrUnsub ( this . _next , value ) ;
134
+ } else if ( this . __tryOrSetError ( _parent , this . _next , value ) ) {
135
+ this . unsubscribe ( ) ;
136
+ }
133
137
}
134
138
}
135
139
136
140
error ( err ?: any ) : void {
137
141
if ( ! this . isStopped ) {
142
+ const { _parent } = this ;
138
143
if ( this . _error ) {
139
- this . __tryOrUnsub ( this . _error , err ) ;
144
+ if ( ! _parent . syncErrorThrowable ) {
145
+ this . __tryOrUnsub ( this . _error , err ) ;
146
+ this . unsubscribe ( ) ;
147
+ } else {
148
+ this . __tryOrSetError ( _parent , this . _error , err ) ;
149
+ this . unsubscribe ( ) ;
150
+ }
151
+ } else if ( ! _parent . syncErrorThrowable ) {
152
+ this . unsubscribe ( ) ;
153
+ throw err ;
154
+ } else {
155
+ _parent . syncErrorValue = err ;
156
+ _parent . syncErrorThrown = true ;
157
+ this . unsubscribe ( ) ;
140
158
}
141
- this . unsubscribe ( ) ;
142
159
}
143
160
}
144
161
145
162
complete ( ) : void {
146
163
if ( ! this . isStopped ) {
164
+ const { _parent } = this ;
147
165
if ( this . _complete ) {
148
- this . __tryOrUnsub ( this . _complete ) ;
166
+ if ( ! _parent . syncErrorThrowable ) {
167
+ this . __tryOrUnsub ( this . _complete ) ;
168
+ this . unsubscribe ( ) ;
169
+ } else {
170
+ this . __tryOrSetError ( _parent , this . _complete ) ;
171
+ this . unsubscribe ( ) ;
172
+ }
173
+ } else {
174
+ this . unsubscribe ( ) ;
149
175
}
176
+ }
177
+ }
178
+
179
+ private __tryOrUnsub ( fn : Function , value ?: any ) : void {
180
+ try {
181
+ fn . call ( this . _context , value ) ;
182
+ } catch ( err ) {
150
183
this . unsubscribe ( ) ;
184
+ throw err ;
151
185
}
152
186
}
153
187
188
+ private __tryOrSetError ( parent : Subscriber < T > , fn : Function , value ?: any ) : boolean {
189
+ try {
190
+ fn . call ( this . _context , value ) ;
191
+ } catch ( err ) {
192
+ parent . syncErrorValue = err ;
193
+ parent . syncErrorThrown = true ;
194
+ return true ;
195
+ }
196
+ return false ;
197
+ }
198
+
154
199
protected _unsubscribe ( ) : void {
155
200
const { _parent } = this ;
156
201
this . _context = null ;
157
202
this . _parent = null ;
158
203
_parent . unsubscribe ( ) ;
159
204
}
160
- }
205
+ }
0 commit comments