Skip to content

Commit d2f6ac7

Browse files
josepotvoliva
authored andcommitted
fix(shareReplay): no longer misses synchronous values from source
* fix(shareReplay): subscribe to subject before source subscription happens * test(shareReplay): improve test on sync source subscription Co-authored-by: Víctor Oliva <[email protected]>
1 parent 3bb2f7f commit d2f6ac7

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

spec/operators/shareReplay-spec.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { expect } from 'chai';
22
import * as sinon from 'sinon';
33
import { hot, cold, expectObservable, expectSubscriptions } from '../helpers/marble-testing';
4-
import { shareReplay, mergeMapTo, retry, take } from 'rxjs/operators';
4+
import { shareReplay, mergeMapTo, retry } from 'rxjs/operators';
55
import { TestScheduler } from 'rxjs/testing';
6-
import { Observable, interval, Operator, Observer, of } from 'rxjs';
6+
import { Observable, Operator, Observer, of, from } from 'rxjs';
77

88
declare function asDiagram(arg: string): Function;
99
declare const rxTestScheduler: TestScheduler;
@@ -243,4 +243,23 @@ describe('shareReplay operator', () => {
243243
done();
244244
});
245245
});
246+
247+
it('should not skip values on a sync source', () => {
248+
const a = from(['a', 'b', 'c', 'd']);
249+
// We would like for the previous line to read like this:
250+
//
251+
// const a = cold('(abcd|)');
252+
//
253+
// However, that would synchronously emit multiple values at frame 0,
254+
// but it's not synchronous upon-subscription.
255+
// TODO: revisit once https://github.com/ReactiveX/rxjs/issues/5523 is fixed
256+
257+
const x = cold( 'x-------x');
258+
const expected = '(abcd)--d';
259+
260+
const shared = a.pipe(shareReplay(1));
261+
const result = x.pipe(mergeMapTo(shared));
262+
expectObservable(result).toBe(expected);
263+
});
264+
246265
});

src/internal/operators/shareReplay.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,11 @@ function shareReplayOperator<T>({
9191

9292
return function shareReplayOperation(this: Subscriber<T>, source: Observable<T>) {
9393
refCount++;
94+
let innerSub: Subscription;
9495
if (!subject || hasError) {
9596
hasError = false;
9697
subject = new ReplaySubject<T>(bufferSize, windowTime, scheduler);
98+
innerSub = subject.subscribe(this);
9799
subscription = source.subscribe({
98100
next(value) { subject.next(value); },
99101
error(err) {
@@ -106,9 +108,10 @@ function shareReplayOperator<T>({
106108
subject.complete();
107109
},
108110
});
111+
} else {
112+
innerSub = subject.subscribe(this);
109113
}
110114

111-
const innerSub = subject.subscribe(this);
112115
this.add(() => {
113116
refCount--;
114117
innerSub.unsubscribe();

0 commit comments

Comments
 (0)