Skip to content

Commit c5239e9

Browse files
committed
feat(expand): now handles promises, iterables and lowercase-o observables
- also minor refactoring to subscribeToResult function
1 parent 24fdd34 commit c5239e9

File tree

6 files changed

+74
-20
lines changed

6 files changed

+74
-20
lines changed

spec/operators/expand-spec.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* globals describe, it, expect, expectObservable, hot, cold */
22
var Rx = require('../../dist/cjs/Rx');
33
var Observable = Rx.Observable;
4+
var Promise = require('promise');
45

56
describe('Observable.prototype.expand()', function () {
67
it('should map and recursively flatten', function() {
@@ -54,4 +55,65 @@ describe('Observable.prototype.expand()', function () {
5455
return Observable.of(x + x); // scalar
5556
})).toBe(expected, values);
5657
});
58+
59+
it('should recursively flatten promises', function(done) {
60+
var expected = [1, 2, 4, 8, 16];
61+
Observable.of(1)
62+
.expand(function(x) {
63+
if(x === 16) {
64+
return Observable.empty();
65+
}
66+
return Promise.resolve(x + x);
67+
})
68+
.subscribe(function(x) {
69+
expect(x).toBe(expected.shift());
70+
}, null, function(){
71+
expect(expected.length).toBe(0);
72+
done();
73+
});
74+
});
75+
76+
it('should recursively flatten Arrays', function(done) {
77+
var expected = [1, 2, 4, 8, 16];
78+
Observable.of(1)
79+
.expand(function(x) {
80+
if(x === 16) {
81+
return Observable.empty();
82+
}
83+
return [x + x];
84+
})
85+
.subscribe(function(x) {
86+
expect(x).toBe(expected.shift());
87+
}, null, function(){
88+
expect(expected.length).toBe(0);
89+
done();
90+
});
91+
});
92+
93+
it('should recursively flatten lowercase-o observables', function(done) {
94+
var expected = [1, 2, 4, 8, 16];
95+
96+
Observable.of(1)
97+
.expand(function(x) {
98+
if(x === 16) {
99+
return Observable.empty();
100+
}
101+
102+
var ish = {
103+
subscribe: function(observer){
104+
observer.next(x + x);
105+
observer.complete();
106+
}
107+
};
108+
109+
ish[Symbol.observable] = function(){ return this; };
110+
return ish;
111+
})
112+
.subscribe(function(x) {
113+
expect(x).toBe(expected.shift());
114+
}, null, function(){
115+
expect(expected.length).toBe(0);
116+
done();
117+
});
118+
});
57119
});

spec/operators/switch-spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ var Promise = require('promise');
55
var Observable = Rx.Observable;
66
var immediateScheduler = Rx.Scheduler.immediate;
77

8-
fdescribe('Observable.prototype.switch()', function(){
8+
describe('Observable.prototype.switch()', function(){
99
it("should switch to each immediately-scheduled inner Observable", function (done) {
1010
var a = Observable.of(1, 2, 3, immediateScheduler);
1111
var b = Observable.of(4, 5, 6, immediateScheduler);

src/operators/expand-support.ts

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import ScalarObservable from '../observables/ScalarObservable';
99

1010
import tryCatch from '../util/tryCatch';
1111
import {errorObject} from '../util/errorObject';
12+
import OuterSubscriber from '../OuterSubscriber';
13+
import subscribeToResult from '../util/subscribeToResult';
1214

1315
export class ExpandOperator<T, R> implements Operator<T, R> {
1416
constructor(private project: (value: T, index: number) => Observable<any>,
@@ -20,11 +22,11 @@ export class ExpandOperator<T, R> implements Operator<T, R> {
2022
}
2123
}
2224

23-
export class ExpandSubscriber<T, R> extends Subscriber<T> {
25+
export class ExpandSubscriber<T, R> extends OuterSubscriber<T, R> {
2426
private index: number = 0;
2527
private active: number = 0;
2628
private hasCompleted: boolean = false;
27-
private buffer: T[];
29+
private buffer: any[];
2830

2931
constructor(destination: Observer<T>, private project: (value: T, index: number) => Observable<R>,
3032
private concurrent: number = Number.POSITIVE_INFINITY) {
@@ -34,7 +36,7 @@ export class ExpandSubscriber<T, R> extends Subscriber<T> {
3436
}
3537
}
3638

37-
_next(value: T) {
39+
_next(value: any) {
3840
const index = this.index++;
3941
this.destination.next(value);
4042
if(this.active < this.concurrent) {
@@ -46,7 +48,7 @@ export class ExpandSubscriber<T, R> extends Subscriber<T> {
4648
this._next(result.value);
4749
} else {
4850
this.active++;
49-
this.add(result.subscribe(new ExpandInnerSubscriber(this.destination, this)));
51+
this.add(subscribeToResult<T, R>(this, result, value, index));
5052
}
5153
}
5254
} else {
@@ -72,18 +74,8 @@ export class ExpandSubscriber<T, R> extends Subscriber<T> {
7274
this.destination.complete();
7375
}
7476
}
75-
}
76-
77-
export class ExpandInnerSubscriber<T, R> extends Subscriber<T> {
78-
constructor(destination: Observer<T>, private parent: ExpandSubscriber<T, R>) {
79-
super(destination);
80-
}
8177

82-
_next(value) {
83-
this.parent._next(value);
84-
}
85-
86-
_complete() {
87-
this.parent.notifyComplete(this);
78+
notifyNext(innerValue: R, outerValue: T, innerIndex: number, outerIndex: number) {
79+
this._next(innerValue);
8880
}
8981
}

src/operators/mergeMap-support.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export class MergeMapSubscriber<T, R, R2> extends OuterSubscriber<T, R> {
5151
}
5252

5353
_innerSub(ish: any, value: T, index: number) {
54-
this.add(subscribeToResult<T,R,R2>(this, ish, value, index));
54+
this.add(subscribeToResult<T, R>(this, ish, value, index));
5555
}
5656

5757
_complete() {

src/operators/mergeMapTo-support.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export class MergeMapToSubscriber<T, R, R2> extends OuterSubscriber<T, R> {
5151
}
5252

5353
_innerSub(ish: any, destination: Observer<R>, resultSelector: (innerValue: R, outerValue: T, innerIndex: number, outerIndex: number) => R2, value: T, index: number) {
54-
this.add(subscribeToResult<T,R,R2>(this, ish, value, index));
54+
this.add(subscribeToResult<T, R>(this, ish, value, index));
5555
}
5656

5757
_complete() {

src/util/subscribeToResult.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import OuterSubscriber from '../OuterSubscriber';
1111

1212
const isArray = Array.isArray;
1313

14-
export default function subscribeToResult<T, R, R2>(outerSubscriber: OuterSubscriber<T, R>,
14+
export default function subscribeToResult<T, R>(outerSubscriber: OuterSubscriber<T, R>,
1515
result: any, outerValue?: T, outerIndex?: number): Subscription<T> {
1616
let destination: Subscriber<R> = new InnerSubscriber(outerSubscriber, outerValue, outerIndex);
1717

0 commit comments

Comments
 (0)