Skip to content

Commit

Permalink
feat(forkJoin): simplify interface
Browse files Browse the repository at this point in the history
- removes resultSelector from forkJoin
- updates tests
  • Loading branch information
benlesh committed Mar 2, 2018
1 parent 582c7be commit 4d2338b
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 169 deletions.
133 changes: 0 additions & 133 deletions spec/observables/forkJoin-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,6 @@ describe('forkJoin', () => {
expectObservable(e2).toBe(expected2, {x: [null, 'b', '3', undefined]});
});

it('should join the last values of the provided observables with selector', () => {
function selector(x: string, y: string, z: string) {
return x + y + z;
}

const e1 = forkJoin(
hot('--a--b--c--d--|'),
hot('(b|)'),
hot('--1--2--3--|'),
selector
);
const expected = '--------------(x|)';

expectObservable(e1).toBe(expected, {x: 'db3'});
});

it('should accept single observable', () => {
const e1 = forkJoin(
hot('--a--b--c--d--|')
Expand All @@ -76,34 +60,6 @@ describe('forkJoin', () => {
expectObservable(e1).toBe(expected, {x: ['d']});
});

it('should accept single observable with selector', () => {
function selector(x: string) {
return x + x;
}

const e1 = forkJoin(
hot('--a--b--c--d--|'),
selector
);
const expected = '--------------(x|)';

expectObservable(e1).toBe(expected, {x: 'dd'});
});

it('should accept array of observable contains single with selector', () => {
function selector(x: string) {
return x + x;
}

const e1 = forkJoin(
[hot('--a--b--c--d--|')],
selector
);
const expected = '--------------(x|)';

expectObservable(e1).toBe(expected, {x: 'dd'});
});

it('should accept lowercase-o observables', () => {
const e1 = forkJoin(
hot('--a--b--c--d--|'),
Expand Down Expand Up @@ -153,22 +109,6 @@ describe('forkJoin', () => {
expectObservable(e1).toBe(expected, {x: ['d', 'b', '3']});
});

it('should accept array of observables with selector', () => {
function selector(x: string, y: string, z: string) {
return x + y + z;
}

const e1 = forkJoin(
[hot('--a--b--c--d--|'),
hot('(b|)'),
hot('--1--2--3--|')],
selector
);
const expected = '--------------(x|)';

expectObservable(e1).toBe(expected, {x: 'db3'});
});

it('should not emit if any of source observable is empty', () => {
const e1 = forkJoin(
hot('--a--b--c--d--|'),
Expand Down Expand Up @@ -244,34 +184,6 @@ describe('forkJoin', () => {
expectObservable(e1).toBe(expected);
});

it('should complete when any of source is empty with selector', () => {
function selector(x: string, y: string) {
return x + y;
}

const e1 = forkJoin(
hot('--a--b--c--d--|'),
hot('---------|'),
selector);
const expected = '---------|';

expectObservable(e1).toBe(expected);
});

it('should emit results by resultselector', () => {
function selector(x: string, y: string) {
return x + y;
}

const e1 = forkJoin(
hot('--a--b--c--d--|'),
hot('---2-----|'),
selector);
const expected = '--------------(x|)';

expectObservable(e1).toBe(expected, {x: 'd2'});
});

it('should raise error when any of source raises error with empty observable', () => {
const e1 = forkJoin(
hot('------#'),
Expand All @@ -290,20 +202,6 @@ describe('forkJoin', () => {
expectObservable(e1).toBe(expected);
});

it('should raise error when any of source raises error with selector with empty observable', () => {
function selector(x: string, y: string) {
return x + y;
}

const e1 = forkJoin(
hot('------#'),
hot('---------|'),
selector);
const expected = '------#';

expectObservable(e1).toBe(expected);
});

it('should raise error when source raises error', () => {
const e1 = forkJoin(
hot('------#'),
Expand All @@ -313,34 +211,6 @@ describe('forkJoin', () => {
expectObservable(e1).toBe(expected);
});

it('should raise error when source raises error with selector', () => {
function selector(x: string, y: string) {
return x + y;
}

const e1 = forkJoin(
hot('------#'),
hot('-------b-|'),
selector);
const expected = '------#';

expectObservable(e1).toBe(expected);
});

it('should raise error when the selector throws', () => {
function selector(x: string, y: string) {
throw 'error';
}

const e1 = forkJoin(
hot('--a-|'),
hot('---b-|'),
selector);
const expected = '-----#';

expectObservable(e1).toBe(expected);
});

it('should allow unsubscribing early and explicitly', () => {
const e1 = hot('--a--^--b--c---d-| ');
const e1subs = '^ ! ';
Expand Down Expand Up @@ -397,7 +267,6 @@ describe('forkJoin', () => {
let c: Promise<boolean>;
let d: Observable<string[]>;
let o1: Observable<[number, string, boolean, string[]]> = forkJoin(a, b, c, d);
let o2: Observable<boolean> = forkJoin(a, b, c, d, (aa, bb, cc, dd) => !!aa && !!bb && cc && !!dd.length);
/* tslint:enable:no-unused-variable */
});

Expand All @@ -406,7 +275,6 @@ describe('forkJoin', () => {
let a: Promise<number>[];
let o1: Observable<number[]> = forkJoin(a);
let o2: Observable<number[]> = forkJoin(...a);
let o3: Observable<number> = forkJoin(a, (...x) => x.length);
/* tslint:enable:no-unused-variable */
});

Expand All @@ -415,7 +283,6 @@ describe('forkJoin', () => {
let a: Observable<number>[];
let o1: Observable<number[]> = forkJoin(a);
let o2: Observable<number[]> = forkJoin(...a);
let o3: Observable<number> = forkJoin(a, (...x) => x.length);
/* tslint:enable:no-unused-variable */
});

Expand Down
45 changes: 9 additions & 36 deletions src/internal/observable/forkJoin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,9 @@ export function forkJoin<T, T2, T3>(v1: ObservableInput<T>, v2: ObservableInput<
export function forkJoin<T, T2, T3, T4>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>): Observable<[T, T2, T3, T4]>;
export function forkJoin<T, T2, T3, T4, T5>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>): Observable<[T, T2, T3, T4, T5]>;
export function forkJoin<T, T2, T3, T4, T5, T6>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>, v6: ObservableInput<T6>): Observable<[T, T2, T3, T4, T5, T6]>;
export function forkJoin<T, R>(v1: ObservableInput<T>, project: (v1: T) => R): Observable<R>;
export function forkJoin<T, T2, R>(v1: ObservableInput<T>, v2: ObservableInput<T2>, project: (v1: T, v2: T2) => R): Observable<R>;
export function forkJoin<T, T2, T3, R>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, project: (v1: T, v2: T2, v3: T3) => R): Observable<R>;
export function forkJoin<T, T2, T3, T4, R>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, project: (v1: T, v2: T2, v3: T3, v4: T4) => R): Observable<R>;
export function forkJoin<T, T2, T3, T4, T5, R>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>, project: (v1: T, v2: T2, v3: T3, v4: T4, v5: T5) => R): Observable<R>;
export function forkJoin<T, T2, T3, T4, T5, T6, R>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>, v6: ObservableInput<T6>, project: (v1: T, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6) => R): Observable<R>;
export function forkJoin<T>(v1: ObservableInput<T>): Observable<T[]>;
export function forkJoin<T>(sources: Array<ObservableInput<T>>): Observable<T[]>;
export function forkJoin<R>(sources: Array<ObservableInput<any>>): Observable<R>;
export function forkJoin<T, R>(sources: Array<ObservableInput<T>>, project: (...values: T[]) => R): Observable<R>;
export function forkJoin<R>(sources: Array<ObservableInput<any>>, project: (...values: any[]) => R): Observable<R>;
export function forkJoin<T>(...sources: Array<ObservableInput<T>>): Observable<T[]>;
export function forkJoin<R>(...sources: Array<ObservableInput<any>>): Observable<R>;
/* tslint:enable:max-line-length */

/**
Expand Down Expand Up @@ -132,20 +123,10 @@ export function forkJoin<R>(...sources: Array<ObservableInput<any>>): Observable
* @name forkJoin
* @owner Observable
*/
export function forkJoin<T, R>(...sources: Array<ObservableInput<T> |
Array<ObservableInput<T>> |
((...values: T[]) => R)>): Observable<R> {
if (sources === null || arguments.length === 0) {
return EMPTY;
}

let resultSelector: (...values: T[]) => R = null;
if (typeof sources[sources.length - 1] === 'function') {
resultSelector = sources.pop() as ((...values: T[]) => R);
}

// if the first and only other argument besides the resultSelector is an array
// assume it's been called with `forkJoin([obs1, obs2, obs3], resultSelector)`
export function forkJoin<T>(...sources: Array<ObservableInput<T> |
Array<ObservableInput<T>>>): Observable<T[]> {
// if the first and only other argument is an array
// assume it's been called with `forkJoin([obs1, obs2, obs3])`
if (sources.length === 1 && isArray(sources[0])) {
sources = sources[0] as Array<ObservableInput<T>>;
}
Expand All @@ -155,7 +136,7 @@ export function forkJoin<T, R>(...sources: Array<ObservableInput<T> |
}

return new Observable(subscriber => {
return new ForkJoinSubscriber(subscriber, sources as Array<ObservableInput<T>>, resultSelector);
return new ForkJoinSubscriber(subscriber, sources as Array<ObservableInput<T>>);
});
}
/**
Expand All @@ -169,8 +150,7 @@ class ForkJoinSubscriber<T, R> extends OuterSubscriber<T, T> {
private haveValues = 0;

constructor(destination: Subscriber<R>,
private sources: Array<ObservableInput<T>>,
private resultSelector?: (...values: T[]) => R) {
private sources: Array<ObservableInput<T>>) {
super(destination);

const len = sources.length;
Expand All @@ -197,7 +177,7 @@ class ForkJoinSubscriber<T, R> extends OuterSubscriber<T, T> {
}

notifyComplete(innerSub: InnerSubscriber<T, T>): void {
const { destination, haveValues, resultSelector, values } = this;
const { destination, haveValues, values } = this;
const len = values.length;

if (!(innerSub as any)._hasValue) {
Expand All @@ -212,14 +192,7 @@ class ForkJoinSubscriber<T, R> extends OuterSubscriber<T, T> {
}

if (haveValues === len) {
let result: R | T[];
try {
result = resultSelector ? resultSelector(...values) : values;
} catch (err) {
destination.error(err);
return;
}
destination.next(result);
destination.next(values);
}

destination.complete();
Expand Down

0 comments on commit 4d2338b

Please sign in to comment.