Skip to content

Commit 7bb8280

Browse files
authored
Merge pull request #2826 from benlesh/lettables2
More lettables
2 parents 76668a9 + 2958917 commit 7bb8280

12 files changed

+340
-187
lines changed

src/observable/combineLatest.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { IScheduler } from '../Scheduler';
33
import { isScheduler } from '../util/isScheduler';
44
import { isArray } from '../util/isArray';
55
import { ArrayObservable } from './ArrayObservable';
6-
import { CombineLatestOperator } from '../operator/combineLatest';
6+
import { CombineLatestOperator } from '../operators/combineLatest';
77

88
/* tslint:disable:max-line-length */
99
export function combineLatest<T, T2>(v1: ObservableInput<T>, v2: ObservableInput<T2>, scheduler?: IScheduler): Observable<[T, T2]>;

src/operator/combineAll.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { CombineLatestOperator } from './combineLatest';
1+
22
import { Observable } from '../Observable';
3+
import { combineAll as higherOrder } from '../operators';
34

45
/**
56
* Converts a higher-order Observable into a first-order Observable by waiting
@@ -42,5 +43,5 @@ import { Observable } from '../Observable';
4243
* @owner Observable
4344
*/
4445
export function combineAll<T, R>(this: Observable<T>, project?: (...values: Array<any>) => R): Observable<R> {
45-
return this.lift(new CombineLatestOperator(project));
46+
return higherOrder(project)(this);
4647
}

src/operator/combineLatest.ts

+3-104
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
11
import { Observable, ObservableInput } from '../Observable';
2-
import { ArrayObservable } from '../observable/ArrayObservable';
3-
import { isArray } from '../util/isArray';
4-
import { Operator } from '../Operator';
5-
import { Subscriber } from '../Subscriber';
6-
import { OuterSubscriber } from '../OuterSubscriber';
7-
import { InnerSubscriber } from '../InnerSubscriber';
8-
import { subscribeToResult } from '../util/subscribeToResult';
9-
const none = {};
2+
import { combineLatest as higherOrder } from '../operators';
103

114
/* tslint:disable:max-line-length */
125
export function combineLatest<T, R>(this: Observable<T>, project: (v1: T) => R): Observable<R>;
@@ -71,99 +64,5 @@ export function combineLatest<T, TOther, R>(this: Observable<T>, array: Observab
7164
export function combineLatest<T, R>(this: Observable<T>, ...observables: Array<ObservableInput<any> |
7265
Array<ObservableInput<any>> |
7366
((...values: Array<any>) => R)>): Observable<R> {
74-
let project: (...values: Array<any>) => R = null;
75-
if (typeof observables[observables.length - 1] === 'function') {
76-
project = <(...values: Array<any>) => R>observables.pop();
77-
}
78-
79-
// if the first and only other argument besides the resultSelector is an array
80-
// assume it's been called with `combineLatest([obs1, obs2, obs3], project)`
81-
if (observables.length === 1 && isArray(observables[0])) {
82-
observables = (<any>observables[0]).slice();
83-
}
84-
85-
observables.unshift(this);
86-
87-
return this.lift.call(new ArrayObservable(observables), new CombineLatestOperator(project));
88-
}
89-
90-
export class CombineLatestOperator<T, R> implements Operator<T, R> {
91-
constructor(private project?: (...values: Array<any>) => R) {
92-
}
93-
94-
call(subscriber: Subscriber<R>, source: any): any {
95-
return source.subscribe(new CombineLatestSubscriber(subscriber, this.project));
96-
}
97-
}
98-
99-
/**
100-
* We need this JSDoc comment for affecting ESDoc.
101-
* @ignore
102-
* @extends {Ignored}
103-
*/
104-
export class CombineLatestSubscriber<T, R> extends OuterSubscriber<T, R> {
105-
private active: number = 0;
106-
private values: any[] = [];
107-
private observables: any[] = [];
108-
private toRespond: number;
109-
110-
constructor(destination: Subscriber<R>, private project?: (...values: Array<any>) => R) {
111-
super(destination);
112-
}
113-
114-
protected _next(observable: any) {
115-
this.values.push(none);
116-
this.observables.push(observable);
117-
}
118-
119-
protected _complete() {
120-
const observables = this.observables;
121-
const len = observables.length;
122-
if (len === 0) {
123-
this.destination.complete();
124-
} else {
125-
this.active = len;
126-
this.toRespond = len;
127-
for (let i = 0; i < len; i++) {
128-
const observable = observables[i];
129-
this.add(subscribeToResult(this, observable, observable, i));
130-
}
131-
}
132-
}
133-
134-
notifyComplete(unused: Subscriber<R>): void {
135-
if ((this.active -= 1) === 0) {
136-
this.destination.complete();
137-
}
138-
}
139-
140-
notifyNext(outerValue: T, innerValue: R,
141-
outerIndex: number, innerIndex: number,
142-
innerSub: InnerSubscriber<T, R>): void {
143-
const values = this.values;
144-
const oldVal = values[outerIndex];
145-
const toRespond = !this.toRespond
146-
? 0
147-
: oldVal === none ? --this.toRespond : this.toRespond;
148-
values[outerIndex] = innerValue;
149-
150-
if (toRespond === 0) {
151-
if (this.project) {
152-
this._tryProject(values);
153-
} else {
154-
this.destination.next(values.slice());
155-
}
156-
}
157-
}
158-
159-
private _tryProject(values: any[]) {
160-
let result: any;
161-
try {
162-
result = this.project.apply(this, values);
163-
} catch (err) {
164-
this.destination.error(err);
165-
return;
166-
}
167-
this.destination.next(result);
168-
}
169-
}
67+
return higherOrder(...observables)(this);
68+
}

src/operator/distinct.ts

+2-73
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
import { Observable } from '../Observable';
2-
import { Operator } from '../Operator';
3-
import { Subscriber } from '../Subscriber';
4-
import { TeardownLogic } from '../Subscription';
5-
import { OuterSubscriber } from '../OuterSubscriber';
6-
import { InnerSubscriber } from '../InnerSubscriber';
7-
import { subscribeToResult } from '../util/subscribeToResult';
8-
import { ISet, Set } from '../util/Set';
2+
import { distinct as higherOrder } from '../operators';
93

104
/**
115
* Returns an Observable that emits all items emitted by the source Observable that are distinct by comparison from previous items.
@@ -55,70 +49,5 @@ import { ISet, Set } from '../util/Set';
5549
export function distinct<T, K>(this: Observable<T>,
5650
keySelector?: (value: T) => K,
5751
flushes?: Observable<any>): Observable<T> {
58-
return this.lift(new DistinctOperator(keySelector, flushes));
59-
}
60-
61-
class DistinctOperator<T, K> implements Operator<T, T> {
62-
constructor(private keySelector: (value: T) => K, private flushes: Observable<any>) {
63-
}
64-
65-
call(subscriber: Subscriber<T>, source: any): TeardownLogic {
66-
return source.subscribe(new DistinctSubscriber(subscriber, this.keySelector, this.flushes));
67-
}
68-
}
69-
70-
/**
71-
* We need this JSDoc comment for affecting ESDoc.
72-
* @ignore
73-
* @extends {Ignored}
74-
*/
75-
export class DistinctSubscriber<T, K> extends OuterSubscriber<T, T> {
76-
private values: ISet<K> = new Set<K>();
77-
78-
constructor(destination: Subscriber<T>, private keySelector: (value: T) => K, flushes: Observable<any>) {
79-
super(destination);
80-
81-
if (flushes) {
82-
this.add(subscribeToResult(this, flushes));
83-
}
84-
}
85-
86-
notifyNext(outerValue: T, innerValue: T,
87-
outerIndex: number, innerIndex: number,
88-
innerSub: InnerSubscriber<T, T>): void {
89-
this.values.clear();
90-
}
91-
92-
notifyError(error: any, innerSub: InnerSubscriber<T, T>): void {
93-
this._error(error);
94-
}
95-
96-
protected _next(value: T): void {
97-
if (this.keySelector) {
98-
this._useKeySelector(value);
99-
} else {
100-
this._finalizeNext(value, value);
101-
}
102-
}
103-
104-
private _useKeySelector(value: T): void {
105-
let key: K;
106-
const { destination } = this;
107-
try {
108-
key = this.keySelector(value);
109-
} catch (err) {
110-
destination.error(err);
111-
return;
112-
}
113-
this._finalizeNext(key, value);
114-
}
115-
116-
private _finalizeNext(key: K|T, value: T) {
117-
const { values } = this;
118-
if (!values.has(<K>key)) {
119-
values.add(<K>key);
120-
this.destination.next(value);
121-
}
122-
}
123-
52+
return higherOrder(keySelector, flushes)(this);
12453
}

src/operator/publishLast.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import { Observable } from '../Observable';
2-
import { AsyncSubject } from '../AsyncSubject';
3-
import { multicast } from './multicast';
42
import { ConnectableObservable } from '../observable/ConnectableObservable';
5-
3+
import { publishLast as higherOrder } from '../operators';
64
/**
75
* @return {ConnectableObservable<T>}
86
* @method publishLast
97
* @owner Observable
108
*/
119
export function publishLast<T>(this: Observable<T>): ConnectableObservable<T> {
12-
return multicast.call(this, new AsyncSubject<T>());
10+
//TODO(benlesh): correct type-flow through here.
11+
return higherOrder()(this) as ConnectableObservable<T>;
1312
}

src/operator/publishReplay.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { Observable } from '../Observable';
2-
import { ReplaySubject } from '../ReplaySubject';
32
import { IScheduler } from '../Scheduler';
4-
import { multicast } from './multicast';
53
import { ConnectableObservable } from '../observable/ConnectableObservable';
4+
import { publishReplay as higherOrder } from '../operators';
65

76
/**
87
* @param bufferSize
@@ -15,5 +14,5 @@ import { ConnectableObservable } from '../observable/ConnectableObservable';
1514
export function publishReplay<T>(this: Observable<T>, bufferSize: number = Number.POSITIVE_INFINITY,
1615
windowTime: number = Number.POSITIVE_INFINITY,
1716
scheduler?: IScheduler): ConnectableObservable<T> {
18-
return multicast.call(this, new ReplaySubject<T>(bufferSize, windowTime, scheduler));
17+
return higherOrder(bufferSize, windowTime, scheduler)(this);
1918
}

src/operators/combineAll.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { CombineLatestOperator } from '../operators/combineLatest';
2+
import { Observable } from '../Observable';
3+
import { OperatorFunction } from '../interfaces';
4+
5+
export function combineAll<T, R>(project?: (...values: Array<any>) => R): OperatorFunction<T, R> {
6+
return (source: Observable<T>) => source.lift(new CombineLatestOperator(project));
7+
}

0 commit comments

Comments
 (0)