Skip to content

Commit

Permalink
fix(first): will now only emit one value in recursive cases (#2100)
Browse files Browse the repository at this point in the history
adds guard after first emitted value to prevent reentrant behavior

fixes #2098
  • Loading branch information
benlesh authored and jayphelps committed Nov 5, 2016
1 parent c83bab9 commit a047e7a
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 3 deletions.
14 changes: 14 additions & 0 deletions spec/operators/first-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ describe('Observable.prototype.first', () => {
expectSubscriptions(e1.subscriptions).toBe(sub);
});

it('should only emit one value in recursive cases', () => {
const subject = new Rx.Subject<number>();
const results = [];

subject.first().subscribe(x => {
results.push(x);
subject.next(x + 1);
});

subject.next(0);

expect(results).to.deep.equal([0]);
});

it('should propagate error from the source observable', () => {
const e1 = hot('---^---#');
const expected = '----#';
Expand Down
10 changes: 7 additions & 3 deletions src/operator/first.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class FirstOperator<T, R> implements Operator<T, R> {
class FirstSubscriber<T, R> extends Subscriber<T> {
private index: number = 0;
private hasCompleted: boolean = false;
private _emitted: boolean = false;

constructor(destination: Subscriber<R>,
private predicate?: (value: T, index: number, source: Observable<T>) => boolean,
Expand Down Expand Up @@ -137,9 +138,12 @@ class FirstSubscriber<T, R> extends Subscriber<T> {

private _emitFinal(value: any) {
const destination = this.destination;
destination.next(value);
destination.complete();
this.hasCompleted = true;
if (!this._emitted) {
this._emitted = true;
destination.next(value);
destination.complete();
this.hasCompleted = true;
}
}

protected _complete(): void {
Expand Down

0 comments on commit a047e7a

Please sign in to comment.