Reputation: 189
I try to use Subject in a multicast to complete but it does not show the completion message as set in the complete()
method. What is the reason? and how are the error and complete methods meant to be used?
let source = new Observable(subscriber => {
subscriber.next(1);
subscriber.next(2);
return () => {
subscriber.complete();
console.log('Unsubscribed');
}
});
let subject = new Subject<number>();
const observer = {
next: (x) => console.log('Observer got a next value: ', x),
error: (err) => console.error('Observer got an error: ', err),
complete: () => console.log('Observer got a complete notification'),
};
subject.subsribe(observer);
const connectableObservable = connectable(source, {
connector: () => subject,
});
const subscription = connectableObservable.connect();
subscription.unsubscribe();
Upvotes: 0
Views: 780
Reputation: 8022
This has nothing to do with a subject or multicasting or anything like that. This is about the Observable contract that RxJS will try to enforce.
You can review Rxjs contract for observables here at this link.
When an observer issues an Unsubscribe notification to an Observable, the Observable will attempt to stop issuing notifications to the observer.
This includes complete
notifications.
Consider the following:
const source = new Observable(observer => {
observer.next(1);
observer.next(2);
observer.complete();
observer.next(3);
return { unsubscribe: () => {
console.log('Unsubscribed');
}};
});
const subscription = source.subscribe({
next: console.log,
complete: () => console.log("Source Complete")
});
subscription.unsubscribe();
subscription.unsubscribe();
subscription.unsubscribe();
The output is this:
1
2
Source Complete
Unsubscribed
You'll notice that you don't see a 3 in the output even though the observable above would emit a 3 after it completes. That's because an RxJS observable guarantees that it won't emit anything after a complete
or error
.
So the above code has been proxied to ensure the contract has been met.
You'll notice that the unsubscribe
code is only ever called once. In fact, in this case, you don't need it at all since a completed observable is automatically unsubscribed.
Consider the following:
const source = new Observable(observer => {
observer.next(1);
observer.complete();
return { unsubscribe: () => {
console.log('Unsubscribed');
}};
});
source.subscribe({
next: console.log,
complete: () => console.log("Source Complete")
});
The output:
1
Source Complete
Unsubscribed
Notice how the unsubscribe code is called even though we never called it ourselves? That, again is part of the Observable contract for RxJS. After the observable terminates (errors or completes), the cleanup code (unsubscribe) is called immediately, then isn't called again.
Upvotes: 2