node_modules updated, buefy add to lib folder

This commit is contained in:
2019-06-04 14:29:48 +02:00
parent 0a3f6ff240
commit 5d28bc36e1
3957 changed files with 306575 additions and 21738 deletions
+12 -1
View File
@@ -3,6 +3,17 @@ import { Observable } from './Observable';
import { empty } from './observable/empty';
import { of } from './observable/of';
import { throwError } from './observable/throwError';
import { deprecate } from 'util';
// TODO: When this enum is removed, replace it with a type alias. See #4556.
/**
* @deprecated NotificationKind is deprecated as const enums are not compatible with isolated modules. Use a string literal instead.
*/
export enum NotificationKind {
NEXT = 'N',
ERROR = 'E',
COMPLETE = 'C',
}
/**
* Represents a push-based event or value that an {@link Observable} can emit.
@@ -21,7 +32,7 @@ import { throwError } from './observable/throwError';
export class Notification<T> {
hasValue: boolean;
constructor(public kind: string, public value?: T, public error?: any) {
constructor(public kind: 'N' | 'E' | 'C', public value?: T, public error?: any) {
this.hasValue = kind === 'N';
}
+37 -22
View File
@@ -6,7 +6,7 @@ import { canReportError } from './util/canReportError';
import { toSubscriber } from './util/toSubscriber';
import { iif } from './observable/iif';
import { throwError } from './observable/throwError';
import { observable as Symbol_observable } from '../internal/symbol/observable';
import { observable as Symbol_observable } from './symbol/observable';
import { pipeFromArray } from './util/pipe';
import { config } from './config';
@@ -50,6 +50,7 @@ export class Observable<T> implements Subscribable<T> {
* @param {Function} subscribe? the subscriber function to be passed to the Observable constructor
* @return {Observable} a new cold observable
* @nocollapse
* @deprecated use new Observable() instead
*/
static create: Function = <T>(subscribe?: (subscriber: Subscriber<T>) => TeardownLogic) => {
return new Observable<T>(subscribe);
@@ -70,6 +71,12 @@ export class Observable<T> implements Subscribable<T> {
}
subscribe(observer?: PartialObserver<T>): Subscription;
/** @deprecated Use an observer instead of a complete callback */
subscribe(next: null | undefined, error: null | undefined, complete: () => void): Subscription;
/** @deprecated Use an observer instead of an error callback */
subscribe(next: null | undefined, error: (error: any) => void, complete?: () => void): Subscription;
/** @deprecated Use an observer instead of a complete callback */
subscribe(next: (value: T) => void, error: null | undefined, complete: () => void): Subscription;
subscribe(next?: (value: T) => void, error?: (error: any) => void, complete?: () => void): Subscription;
/**
* Invokes an execution of an Observable and registers Observer handlers for notifications it will emit.
@@ -113,22 +120,26 @@ export class Observable<T> implements Subscribable<T> {
*
* ## Example
* ### Subscribe with an Observer
* ```javascript
* ```ts
* import { of } from 'rxjs';
*
* const sumObserver = {
* sum: 0,
* next(value) {
* console.log('Adding: ' + value);
* this.sum = this.sum + value;
* },
* error() { // We actually could just remove this method,
* }, // since we do not really care about errors right now.
* error() {
* // We actually could just remove this method,
* // since we do not really care about errors right now.
* },
* complete() {
* console.log('Sum equals: ' + this.sum);
* }
* };
*
* Rx.Observable.of(1, 2, 3) // Synchronously emits 1, 2, 3 and then completes.
* .subscribe(sumObserver);
* of(1, 2, 3) // Synchronously emits 1, 2, 3 and then completes.
* .subscribe(sumObserver);
*
* // Logs:
* // "Adding: 1"
@@ -138,19 +149,18 @@ export class Observable<T> implements Subscribable<T> {
* ```
*
* ### Subscribe with functions
* ```javascript
* ```ts
* import { of } from 'rxjs'
*
* let sum = 0;
*
* Rx.Observable.of(1, 2, 3)
* .subscribe(
* function(value) {
* of(1, 2, 3).subscribe(
* value => {
* console.log('Adding: ' + value);
* sum = sum + value;
* },
* undefined,
* function() {
* console.log('Sum equals: ' + sum);
* }
* () => console.log('Sum equals: ' + sum)
* );
*
* // Logs:
@@ -161,13 +171,17 @@ export class Observable<T> implements Subscribable<T> {
* ```
*
* ### Cancel a subscription
* ```javascript
* const subscription = Rx.Observable.interval(1000).subscribe(
* ```ts
* import { interval } from 'rxjs';
*
* const subscription = interval(1000).subscribe(
* num => console.log(num),
* undefined,
* () => console.log('completed!') // Will not be called, even
* ); // when cancelling subscription
*
* () => {
* // Will not be called, even when cancelling subscription.
* console.log('completed!');
* }
* );
*
* setTimeout(() => {
* subscription.unsubscribe();
@@ -197,7 +211,7 @@ export class Observable<T> implements Subscribable<T> {
const sink = toSubscriber(observerOrNext, error, complete);
if (operator) {
operator.call(sink, this.source);
sink.add(operator.call(sink, this.source));
} else {
sink.add(
this.source || (config.useDeprecatedSynchronousErrorHandling && !sink.syncErrorThrowable) ?
@@ -246,7 +260,7 @@ export class Observable<T> implements Subscribable<T> {
promiseCtor = getPromiseCtor(promiseCtor);
return new promiseCtor<void>((resolve, reject) => {
// Must be declared in a separate statement to avoid a RefernceError when
// Must be declared in a separate statement to avoid a ReferenceError when
// accessing subscription below in the closure due to Temporal Dead Zone.
let subscription: Subscription;
subscription = this.subscribe((value) => {
@@ -311,10 +325,11 @@ export class Observable<T> implements Subscribable<T> {
* been called in the order they were passed in.
*
* ### Example
* ```javascript
* ```ts
* import { interval } from 'rxjs';
* import { map, filter, scan } from 'rxjs/operators';
*
* Rx.Observable.interval(1000)
* interval(1000)
* .pipe(
* filter(x => x % 2 === 0),
* map(x => x + x),
+1 -1
View File
@@ -153,7 +153,7 @@ export {AsyncSubject} from './AsyncSubject';
export {ReplaySubject} from './ReplaySubject';
export {BehaviorSubject} from './BehaviorSubject';
export {ConnectableObservable} from './observable/ConnectableObservable';
export {Notification} from './Notification';
export {Notification, NotificationKind} from './Notification';
export {EmptyError} from './util/EmptyError';
export {ArgumentOutOfRangeError} from './util/ArgumentOutOfRangeError';
export {ObjectUnsubscribedError} from './util/ObjectUnsubscribedError';
+4 -2
View File
@@ -18,7 +18,7 @@ export class SubjectSubscriber<T> extends Subscriber<T> {
/**
* A Subject is a special type of Observable that allows values to be
* multicasted to many Observables. Subjects are like EventEmitters.
* multicasted to many Observers. Subjects are like EventEmitters.
*
* Every Subject is an Observable and an Observer. You can subscribe to a
* Subject, and you can call next to feed values as well as error and complete.
@@ -45,7 +45,9 @@ export class Subject<T> extends Observable<T> implements SubscriptionLike {
super();
}
/**@nocollapse */
/**@nocollapse
* @deprecated use new Subject() instead
*/
static create: Function = <T>(destination: Observer<T>, source: Observable<T>): AnonymousSubject<T> => {
return new AnonymousSubject<T>(destination, source);
}
+3 -8
View File
@@ -47,8 +47,6 @@ export class Subscriber<T> extends Subscription implements Observer<T> {
protected isStopped: boolean = false;
protected destination: PartialObserver<any> | Subscriber<any>; // this `any` is the escape hatch to erase extra type param (e.g. R)
private _parentSubscription: Subscription | null = null;
/**
* @param {Observer|function(value: T): void} [destinationOrNext] A partially
* defined Observer or a `next` callback function.
@@ -153,15 +151,12 @@ export class Subscriber<T> extends Subscription implements Observer<T> {
/** @deprecated This is an internal implementation detail, do not use. */
_unsubscribeAndRecycle(): Subscriber<T> {
const { _parent, _parents } = this;
this._parent = null;
this._parents = null;
const { _parentOrParents } = this;
this._parentOrParents = null;
this.unsubscribe();
this.closed = false;
this.isStopped = false;
this._parent = _parent;
this._parents = _parents;
this._parentSubscription = null;
this._parentOrParents = _parentOrParents;
return this;
}
}
+63 -69
View File
@@ -1,8 +1,6 @@
import { isArray } from './util/isArray';
import { isObject } from './util/isObject';
import { isFunction } from './util/isFunction';
import { tryCatch } from './util/tryCatch';
import { errorObject } from './util/errorObject';
import { UnsubscriptionError } from './util/UnsubscriptionError';
import { SubscriptionLike, TeardownLogic } from './types';
@@ -32,9 +30,7 @@ export class Subscription implements SubscriptionLike {
public closed: boolean = false;
/** @internal */
protected _parent: Subscription = null;
/** @internal */
protected _parents: Subscription[] = null;
protected _parentOrParents: Subscription | Subscription[] = null;
/** @internal */
private _subscriptions: SubscriptionLike[] = null;
@@ -55,76 +51,66 @@ export class Subscription implements SubscriptionLike {
* @return {void}
*/
unsubscribe(): void {
let hasErrors = false;
let errors: any[];
if (this.closed) {
return;
}
let { _parent, _parents, _unsubscribe, _subscriptions } = (<any> this);
let { _parentOrParents, _unsubscribe, _subscriptions } = (<any> this);
this.closed = true;
this._parent = null;
this._parents = null;
this._parentOrParents = null;
// null out _subscriptions first so any child subscriptions that attempt
// to remove themselves from this subscription will noop
this._subscriptions = null;
let index = -1;
let len = _parents ? _parents.length : 0;
// if this._parent is null, then so is this._parents, and we
// don't have to remove ourselves from any parent subscriptions.
while (_parent) {
_parent.remove(this);
// if this._parents is null or index >= len,
// then _parent is set to null, and the loop exits
_parent = ++index < len && _parents[index] || null;
if (_parentOrParents instanceof Subscription) {
_parentOrParents.remove(this);
} else if (_parentOrParents !== null) {
for (let index = 0; index < _parentOrParents.length; ++index) {
const parent = _parentOrParents[index];
parent.remove(this);
}
}
if (isFunction(_unsubscribe)) {
let trial = tryCatch(_unsubscribe).call(this);
if (trial === errorObject) {
hasErrors = true;
errors = errors || (
errorObject.e instanceof UnsubscriptionError ?
flattenUnsubscriptionErrors(errorObject.e.errors) : [errorObject.e]
);
try {
_unsubscribe.call(this);
} catch (e) {
errors = e instanceof UnsubscriptionError ? flattenUnsubscriptionErrors(e.errors) : [e];
}
}
if (isArray(_subscriptions)) {
index = -1;
len = _subscriptions.length;
let index = -1;
let len = _subscriptions.length;
while (++index < len) {
const sub = _subscriptions[index];
if (isObject(sub)) {
let trial = tryCatch(sub.unsubscribe).call(sub);
if (trial === errorObject) {
hasErrors = true;
try {
sub.unsubscribe();
} catch (e) {
errors = errors || [];
let err = errorObject.e;
if (err instanceof UnsubscriptionError) {
errors = errors.concat(flattenUnsubscriptionErrors(err.errors));
if (e instanceof UnsubscriptionError) {
errors = errors.concat(flattenUnsubscriptionErrors(e.errors));
} else {
errors.push(err);
errors.push(e);
}
}
}
}
}
if (hasErrors) {
if (errors) {
throw new UnsubscriptionError(errors);
}
}
/**
* Adds a tear down to be called during the unsubscribe() of this
* Subscription.
* Subscription. Can also be used to add a child subscription.
*
* If the tear down being added is a subscription that is already
* unsubscribed, is the same reference `add` is being called on, or is
@@ -133,6 +119,8 @@ export class Subscription implements SubscriptionLike {
* If this subscription is already in an `closed` state, the passed
* tear down logic will be executed immediately.
*
* When a parent subscription is unsubscribed, any child subscriptions that were added to it are also unsubscribed.
*
* @param {TeardownLogic} teardown The additional logic to execute on
* teardown.
* @return {Subscription} Returns the Subscription used or created to be
@@ -141,39 +129,62 @@ export class Subscription implements SubscriptionLike {
* list.
*/
add(teardown: TeardownLogic): Subscription {
if (!teardown || (teardown === Subscription.EMPTY)) {
let subscription = (<Subscription>teardown);
if (!(<any>teardown)) {
return Subscription.EMPTY;
}
if (teardown === this) {
return this;
}
let subscription = (<Subscription> teardown);
switch (typeof teardown) {
case 'function':
subscription = new Subscription(<(() => void) > teardown);
subscription = new Subscription(<(() => void)>teardown);
case 'object':
if (subscription.closed || typeof subscription.unsubscribe !== 'function') {
if (subscription === this || subscription.closed || typeof subscription.unsubscribe !== 'function') {
// This also covers the case where `subscription` is `Subscription.EMPTY`, which is always in `closed` state.
return subscription;
} else if (this.closed) {
subscription.unsubscribe();
return subscription;
} else if (typeof subscription._addParent !== 'function' /* quack quack */) {
} else if (!(subscription instanceof Subscription)) {
const tmp = subscription;
subscription = new Subscription();
subscription._subscriptions = [tmp];
}
break;
default:
default: {
throw new Error('unrecognized teardown ' + teardown + ' added to Subscription.');
}
}
const subscriptions = this._subscriptions || (this._subscriptions = []);
// Add `this` as parent of `subscription` if that's not already the case.
let { _parentOrParents } = subscription;
if (_parentOrParents === null) {
// If we don't have a parent, then set `subscription._parents` to
// the `this`, which is the common case that we optimize for.
subscription._parentOrParents = this;
} else if (_parentOrParents instanceof Subscription) {
if (_parentOrParents === this) {
// The `subscription` already has `this` as a parent.
return subscription;
}
// If there's already one parent, but not multiple, allocate an
// Array to store the rest of the parent Subscriptions.
subscription._parentOrParents = [_parentOrParents, this];
} else if (_parentOrParents.indexOf(this) === -1) {
// Only add `this` to the _parentOrParents list if it's not already there.
_parentOrParents.push(this);
} else {
// The `subscription` already has `this` as a parent.
return subscription;
}
subscriptions.push(subscription);
subscription._addParent(this);
// Optimize for the common case when adding the first subscription.
const subscriptions = this._subscriptions;
if (subscriptions === null) {
this._subscriptions = [subscription];
} else {
subscriptions.push(subscription);
}
return subscription;
}
@@ -193,23 +204,6 @@ export class Subscription implements SubscriptionLike {
}
}
}
/** @internal */
private _addParent(parent: Subscription) {
let { _parent, _parents } = this;
if (!_parent || _parent === parent) {
// If we don't have a parent, or the new parent is the same as the
// current parent, then set this._parent to the new parent.
this._parent = parent;
} else if (!_parents) {
// If there's already one parent, but not multiple, allocate an Array to
// store the rest of the parent Subscriptions.
this._parents = [parent];
} else if (_parents.indexOf(parent) === -1) {
// Only add the new parent to the _parents list if it's not already there.
_parents.push(parent);
}
}
}
function flattenUnsubscriptionErrors(errors: any[]) {
-2
View File
@@ -45,8 +45,6 @@ export class ConnectableObservable<T> extends Observable<T> {
if (connection.closed) {
this._connection = null;
connection = Subscription.EMPTY;
} else {
this._connection = connection;
}
}
return connection;
+15 -6
View File
@@ -111,7 +111,10 @@ export function bindCallback(callbackFunc: Function, scheduler?: SchedulerLike):
* ## Examples
*
* ### Convert jQuery's getJSON to an Observable API
* ```javascript
* ```ts
* import { bindCallback } from 'rxjs';
* import * as jQuery from 'jquery';
*
* // Suppose we have jQuery.getJSON('/my/url', callback)
* const getJSONAsObservable = bindCallback(jQuery.getJSON);
* const result = getJSONAsObservable('/my/url');
@@ -119,12 +122,14 @@ export function bindCallback(callbackFunc: Function, scheduler?: SchedulerLike):
* ```
*
* ### Receive an array of arguments passed to a callback
* ```javascript
* someFunction((a, b, c) => {
* ```ts
* import { bindCallback } from 'rxjs';
*
* const someFunction = (a, b, c) => {
* console.log(a); // 5
* console.log(b); // 'some string'
* console.log(c); // {someProperty: 'someValue'}
* });
* };
*
* const boundSomeFunction = bindCallback(someFunction);
* boundSomeFunction().subscribe(values => {
@@ -133,7 +138,9 @@ export function bindCallback(callbackFunc: Function, scheduler?: SchedulerLike):
* ```
*
* ### Compare behaviour with and without async Scheduler
* ```javascript
* ```ts
* import { bindCallback } from 'rxjs';
*
* function iCallMyCallbackSynchronously(cb) {
* cb();
* }
@@ -152,7 +159,9 @@ export function bindCallback(callbackFunc: Function, scheduler?: SchedulerLike):
* ```
*
* ### Use bindCallback on an object method
* ```javascript
* ```ts
* import { bindCallback } from 'rxjs';
*
* const boundMethod = bindCallback(someObject.methodWithCallback);
* boundMethod.call(someObject) // make sure methodWithCallback has access to someObject
* .subscribe(subscriber);
+3 -3
View File
@@ -108,7 +108,7 @@ export function bindNodeCallback(callbackFunc: Function, scheduler?: SchedulerLi
*
* ## Examples
* ### Read a file from the filesystem and get the data as an Observable
* ```javascript
* ```ts
* import * as fs from 'fs';
* const readFileAsObservable = bindNodeCallback(fs.readFile);
* const result = readFileAsObservable('./roadNames.txt', 'utf8');
@@ -116,7 +116,7 @@ export function bindNodeCallback(callbackFunc: Function, scheduler?: SchedulerLi
* ```
*
* ### Use on function calling callback with multiple arguments
* ```javascript
* ```ts
* someFunction((err, a, b) => {
* console.log(err); // null
* console.log(a); // 5
@@ -130,7 +130,7 @@ export function bindNodeCallback(callbackFunc: Function, scheduler?: SchedulerLi
* ```
*
* ### Use on function calling callback in regular style
* ```javascript
* ```ts
* someFunction(a => {
* console.log(a); // 5
* });
+102 -36
View File
@@ -1,5 +1,5 @@
import { Observable } from '../Observable';
import { ObservableInput, SchedulerLike } from '../types';
import { ObservableInput, SchedulerLike, ObservedValueOf } from '../types';
import { isScheduler } from '../util/isScheduler';
import { isArray } from '../util/isArray';
import { Subscriber } from '../Subscriber';
@@ -12,33 +12,92 @@ import { fromArray } from './fromArray';
const NONE = {};
/* tslint:disable:max-line-length */
/** @deprecated resultSelector no longer supported, pipe to map instead */
export function combineLatest<T, R>(v1: ObservableInput<T>, resultSelector: (v1: T) => R, scheduler?: SchedulerLike): Observable<R>;
/** @deprecated resultSelector no longer supported, pipe to map instead */
export function combineLatest<T, T2, R>(v1: ObservableInput<T>, v2: ObservableInput<T2>, resultSelector: (v1: T, v2: T2) => R, scheduler?: SchedulerLike): Observable<R>;
/** @deprecated resultSelector no longer supported, pipe to map instead */
export function combineLatest<T, T2, T3, R>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, resultSelector: (v1: T, v2: T2, v3: T3) => R, scheduler?: SchedulerLike): Observable<R>;
/** @deprecated resultSelector no longer supported, pipe to map instead */
export function combineLatest<T, T2, T3, T4, R>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, resultSelector: (v1: T, v2: T2, v3: T3, v4: T4) => R, scheduler?: SchedulerLike): Observable<R>;
/** @deprecated resultSelector no longer supported, pipe to map instead */
export function combineLatest<T, T2, T3, T4, T5, R>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>, resultSelector: (v1: T, v2: T2, v3: T3, v4: T4, v5: T5) => R, scheduler?: SchedulerLike): Observable<R>;
/** @deprecated resultSelector no longer supported, pipe to map instead */
export function combineLatest<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>, resultSelector: (v1: T, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6) => R, scheduler?: SchedulerLike): Observable<R>;
export function combineLatest<T, T2>(v1: ObservableInput<T>, v2: ObservableInput<T2>, scheduler?: SchedulerLike): Observable<[T, T2]>;
export function combineLatest<T, T2, T3>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, scheduler?: SchedulerLike): Observable<[T, T2, T3]>;
export function combineLatest<T, T2, T3, T4>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, scheduler?: SchedulerLike): Observable<[T, T2, T3, T4]>;
export function combineLatest<T, T2, T3, T4, T5>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>, scheduler?: SchedulerLike): Observable<[T, T2, T3, T4, T5]>;
export function combineLatest<T, T2, T3, T4, T5, T6>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>, v6: ObservableInput<T6>, scheduler?: SchedulerLike): Observable<[T, T2, T3, T4, T5, T6]>;
// If called with a single array, it "auto-spreads" the array, with result selector
/** @deprecated resultSelector no longer supported, pipe to map instead */
export function combineLatest<O1 extends ObservableInput<any>, R>(sources: [O1], resultSelector: (v1: ObservedValueOf<O1>) => R, scheduler?: SchedulerLike): Observable<R>;
/** @deprecated resultSelector no longer supported, pipe to map instead */
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, R>(sources: [O1, O2], resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>) => R, scheduler?: SchedulerLike): Observable<R>;
/** @deprecated resultSelector no longer supported, pipe to map instead */
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, R>(sources: [O1, O2, O3], resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>) => R, scheduler?: SchedulerLike): Observable<R>;
/** @deprecated resultSelector no longer supported, pipe to map instead */
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, R>(sources: [O1, O2, O3, O4], resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>) => R, scheduler?: SchedulerLike): Observable<R>;
/** @deprecated resultSelector no longer supported, pipe to map instead */
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, O5 extends ObservableInput<any>, R>(sources: [O1, O2, O3, O4, O5], resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>, v5: ObservedValueOf<O5>) => R, scheduler?: SchedulerLike): Observable<R>;
/** @deprecated resultSelector no longer supported, pipe to map instead */
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, O5 extends ObservableInput<any>, O6 extends ObservableInput<any>, R>(sources: [O1, O2, O3, O4, O5, O6], resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>, v5: ObservedValueOf<O5>, v6: ObservedValueOf<O6>) => R, scheduler?: SchedulerLike): Observable<R>;
/** @deprecated resultSelector no longer supported, pipe to map instead */
export function combineLatest<O extends ObservableInput<any>, R>(sources: O[], resultSelector: (...args: ObservedValueOf<O>[]) => R, scheduler?: SchedulerLike): Observable<R>;
export function combineLatest<T>(array: ObservableInput<T>[], scheduler?: SchedulerLike): Observable<T[]>;
export function combineLatest<R>(array: ObservableInput<any>[], scheduler?: SchedulerLike): Observable<R>;
// standard call, but with a result selector
/** @deprecated resultSelector no longer supported, pipe to map instead */
export function combineLatest<T, R>(array: ObservableInput<T>[], resultSelector: (...values: Array<T>) => R, scheduler?: SchedulerLike): Observable<R>;
export function combineLatest<O1 extends ObservableInput<any>, R>(v1: O1, resultSelector: (v1: ObservedValueOf<O1>) => R, scheduler?: SchedulerLike): Observable<R>;
/** @deprecated resultSelector no longer supported, pipe to map instead */
export function combineLatest<R>(array: ObservableInput<any>[], resultSelector: (...values: Array<any>) => R, scheduler?: SchedulerLike): Observable<R>;
export function combineLatest<T>(...observables: Array<ObservableInput<T> | SchedulerLike>): Observable<T[]>;
export function combineLatest<T, R>(...observables: Array<ObservableInput<T> | ((...values: Array<T>) => R) | SchedulerLike>): Observable<R>;
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, R>(v1: O1, v2: O2, resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>) => R, scheduler?: SchedulerLike): Observable<R>;
/** @deprecated resultSelector no longer supported, pipe to map instead */
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, R>(v1: O1, v2: O2, v3: O3, resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>) => R, scheduler?: SchedulerLike): Observable<R>;
/** @deprecated resultSelector no longer supported, pipe to map instead */
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, R>(v1: O1, v2: O2, v3: O3, v4: O4, resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>) => R, scheduler?: SchedulerLike): Observable<R>;
/** @deprecated resultSelector no longer supported, pipe to map instead */
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, O5 extends ObservableInput<any>, R>(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>, v5: ObservedValueOf<O5>) => R, scheduler?: SchedulerLike): Observable<R>;
/** @deprecated resultSelector no longer supported, pipe to map instead */
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, O5 extends ObservableInput<any>, O6 extends ObservableInput<any>, R>(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, v6: O6, resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>, v5: ObservedValueOf<O5>, v6: ObservedValueOf<O6>) => R, scheduler?: SchedulerLike): Observable<R>;
// With a scheduler (deprecated)
/** @deprecated Passing a scheduler here is deprecated, use {@link subscribeOn} and/or {@link observeOn} instead */
export function combineLatest<O1 extends ObservableInput<any>>(sources: [O1], scheduler: SchedulerLike): Observable<[ObservedValueOf<O1>]>;
/** @deprecated Passing a scheduler here is deprecated, use {@link subscribeOn} and/or {@link observeOn} instead */
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>>(sources: [O1, O2], scheduler: SchedulerLike): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>]>;
/** @deprecated Passing a scheduler here is deprecated, use {@link subscribeOn} and/or {@link observeOn} instead */
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>>(sources: [O1, O2, O3], scheduler: SchedulerLike): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>]>;
/** @deprecated Passing a scheduler here is deprecated, use {@link subscribeOn} and/or {@link observeOn} instead */
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>>(sources: [O1, O2, O3, O4], scheduler: SchedulerLike): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>]>;
/** @deprecated Passing a scheduler here is deprecated, use {@link subscribeOn} and/or {@link observeOn} instead */
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, O5 extends ObservableInput<any>>(sources: [O1, O2, O3, O4, O5], scheduler: SchedulerLike): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>]>;
/** @deprecated Passing a scheduler here is deprecated, use {@link subscribeOn} and/or {@link observeOn} instead */
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, O5 extends ObservableInput<any>, O6 extends ObservableInput<any>>(sources: [O1, O2, O3, O4, O5, O6], scheduler: SchedulerLike): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>, ObservedValueOf<O6>]>;
/** @deprecated Passing a scheduler here is deprecated, use {@link subscribeOn} and/or {@link observeOn} instead */
export function combineLatest<O extends ObservableInput<any>>(sources: O[], scheduler: SchedulerLike): Observable<ObservedValueOf<O>[]>;
// Best case
export function combineLatest<O1 extends ObservableInput<any>>(sources: [O1]): Observable<[ObservedValueOf<O1>]>;
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>>(sources: [O1, O2]): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>]>;
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>>(sources: [O1, O2, O3]): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>]>;
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>>(sources: [O1, O2, O3, O4]): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>]>;
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, O5 extends ObservableInput<any>>(sources: [O1, O2, O3, O4, O5]): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>]>;
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, O5 extends ObservableInput<any>, O6 extends ObservableInput<any>>(sources: [O1, O2, O3, O4, O5, O6]): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>, ObservedValueOf<O6>]>;
export function combineLatest<O extends ObservableInput<any>>(sources: O[]): Observable<ObservedValueOf<O>[]>;
// Standard calls
/** @deprecated Pass arguments in a single array instead `combineLatest([a, b, c])` */
export function combineLatest<O1 extends ObservableInput<any>>(v1: O1, scheduler?: SchedulerLike): Observable<[ObservedValueOf<O1>]>;
/** @deprecated Pass arguments in a single array instead `combineLatest([a, b, c])` */
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>>(v1: O1, v2: O2, scheduler?: SchedulerLike): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>]>;
/** @deprecated Pass arguments in a single array instead `combineLatest([a, b, c])` */
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>>(v1: O1, v2: O2, v3: O3, scheduler?: SchedulerLike): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>]>;
/** @deprecated Pass arguments in a single array instead `combineLatest([a, b, c])` */
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>>(v1: O1, v2: O2, v3: O3, v4: O4, scheduler?: SchedulerLike): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>]>;
/** @deprecated Pass arguments in a single array instead `combineLatest([a, b, c])` */
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, O5 extends ObservableInput<any>>(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, scheduler?: SchedulerLike): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>]>;
/** @deprecated Pass arguments in a single array instead `combineLatest([a, b, c])` */
export function combineLatest<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, O5 extends ObservableInput<any>, O6 extends ObservableInput<any>>(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, v6: O6, scheduler?: SchedulerLike): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>, ObservedValueOf<O6>]>;
/** @deprecated Pass arguments in a single array instead `combineLatest([a, b, c])` */
export function combineLatest<O extends ObservableInput<any>>(...observables: O[]): Observable<any[]>;
/** @deprecated Pass arguments in a single array instead `combineLatest([a, b, c])` */
export function combineLatest<O extends ObservableInput<any>, R>(...observables: Array<ObservableInput<any> | ((...values: Array<any>) => R)>): Observable<R>;
/** @deprecated resultSelector no longer supported, pipe to map instead */
export function combineLatest<O extends ObservableInput<any>, R>(array: O[], resultSelector: (...values: ObservedValueOf<O>[]) => R, scheduler?: SchedulerLike): Observable<R>;
/** @deprecated Passing a scheduler here is deprecated, use {@link subscribeOn} and/or {@link observeOn} instead */
export function combineLatest<O extends ObservableInput<any>>(...observables: Array<O | SchedulerLike>): Observable<any[]>;
/** @deprecated Passing a scheduler here is deprecated, use {@link subscribeOn} and/or {@link observeOn} instead */
export function combineLatest<O extends ObservableInput<any>, R>(...observables: Array<O | ((...values: ObservedValueOf<O>[]) => R) | SchedulerLike>): Observable<R>;
/** @deprecated Passing a scheduler here is deprecated, use {@link subscribeOn} and/or {@link observeOn} instead */
export function combineLatest<R>(...observables: Array<ObservableInput<any> | ((...values: Array<any>) => R) | SchedulerLike>): Observable<R>;
/* tslint:enable:max-line-length */
@@ -95,7 +154,9 @@ export function combineLatest<R>(...observables: Array<ObservableInput<any> | ((
*
* ## Examples
* ### Combine two timer Observables
* ```javascript
* ```ts
* import { combineLatest, timer } from 'rxjs';
*
* const firstTimer = timer(0, 1000); // emit 0, 1, 2... after every second, starting from now
* const secondTimer = timer(500, 1000); // emit 0, 1, 2... after every second, starting 0,5s from now
* const combinedTimers = combineLatest(firstTimer, secondTimer);
@@ -108,7 +169,10 @@ export function combineLatest<R>(...observables: Array<ObservableInput<any> | ((
* ```
*
* ### Combine an array of Observables
* ```javascript
* ```ts
* import { combineLatest, of } from 'rxjs';
* import { delay, starWith } from 'rxjs/operators';
*
* const observables = [1, 5, 10].map(
* n => of(n).pipe(
* delay(n * 1000), // emit 0 and then emit n after n seconds
@@ -126,8 +190,11 @@ export function combineLatest<R>(...observables: Array<ObservableInput<any> | ((
*
*
* ### Use project function to dynamically calculate the Body-Mass Index
* ```javascript
* * const weight = of(70, 72, 76, 79, 75);
* ```ts
* import { combineLatest, of } from 'rxjs';
* import { map } from 'rxjs/operators';
*
* const weight = of(70, 72, 76, 79, 75);
* const height = of(1.76, 1.77, 1.78);
* const bmi = combineLatest(weight, height).pipe(
* map(([w, h]) => w / (h * h)),
@@ -156,28 +223,27 @@ export function combineLatest<R>(...observables: Array<ObservableInput<any> | ((
* values from each input Observable, or an array of the most recent values from
* each input Observable.
*/
export function combineLatest<T, R>(...observables: Array<any | ObservableInput<any> |
Array<ObservableInput<any>> |
(((...values: Array<any>) => R)) |
SchedulerLike>): Observable<R> {
export function combineLatest<O extends ObservableInput<any>, R>(
...observables: (O | ((...values: ObservedValueOf<O>[]) => R) | SchedulerLike)[]
): Observable<R> {
let resultSelector: (...values: Array<any>) => R = null;
let scheduler: SchedulerLike = null;
if (isScheduler(observables[observables.length - 1])) {
scheduler = <SchedulerLike>observables.pop();
scheduler = observables.pop() as SchedulerLike;
}
if (typeof observables[observables.length - 1] === 'function') {
resultSelector = <(...values: Array<any>) => R>observables.pop();
resultSelector = observables.pop() as (...values: Array<any>) => R;
}
// if the first and only other argument besides the resultSelector is an array
// assume it's been called with `combineLatest([obs1, obs2, obs3], resultSelector)`
if (observables.length === 1 && isArray(observables[0])) {
observables = <Array<Observable<any>>>observables[0];
observables = observables[0] as any;
}
return fromArray(observables, scheduler).lift(new CombineLatestOperator<T, R>(resultSelector));
return fromArray(observables, scheduler).lift(new CombineLatestOperator<ObservedValueOf<O>, R>(resultSelector));
}
export class CombineLatestOperator<T, R> implements Operator<T, R> {
+43 -19
View File
@@ -1,19 +1,36 @@
import { Observable } from '../Observable';
import { ObservableInput, SchedulerLike } from '../types';
import { ObservableInput, SchedulerLike, ObservedValueOf } from '../types';
import { isScheduler } from '../util/isScheduler';
import { of } from './of';
import { from } from './from';
import { concatAll } from '../operators/concatAll';
/* tslint:disable:max-line-length */
export function concat<T>(v1: ObservableInput<T>, scheduler?: SchedulerLike): Observable<T>;
export function concat<T, T2>(v1: ObservableInput<T>, v2: ObservableInput<T2>, scheduler?: SchedulerLike): Observable<T | T2>;
export function concat<T, T2, T3>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, scheduler?: SchedulerLike): Observable<T | T2 | T3>;
export function concat<T, T2, T3, T4>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, scheduler?: SchedulerLike): Observable<T | T2 | T3 | T4>;
export function concat<T, T2, T3, T4, T5>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>, scheduler?: SchedulerLike): Observable<T | T2 | T3 | T4 | T5>;
export function concat<T, T2, T3, T4, T5, T6>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>, v6: ObservableInput<T6>, scheduler?: SchedulerLike): Observable<T | T2 | T3 | T4 | T5 | T6>;
export function concat<T>(...observables: (ObservableInput<T> | SchedulerLike)[]): Observable<T>;
export function concat<T, R>(...observables: (ObservableInput<any> | SchedulerLike)[]): Observable<R>;
/** @deprecated Use {@link scheduled} and {@link concatAll} (e.g. `scheduled([o1, o2, o3], scheduler).pipe(concatAll())`) */
export function concat<O1 extends ObservableInput<any>>(v1: O1, scheduler: SchedulerLike): Observable<ObservedValueOf<O1>>;
/** @deprecated Use {@link scheduled} and {@link concatAll} (e.g. `scheduled([o1, o2, o3], scheduler).pipe(concatAll())`) */
export function concat<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>>(v1: O1, v2: O2, scheduler: SchedulerLike): Observable<ObservedValueOf<O1> | ObservedValueOf<O2>>;
/** @deprecated Use {@link scheduled} and {@link concatAll} (e.g. `scheduled([o1, o2, o3], scheduler).pipe(concatAll())`) */
export function concat<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>>(v1: O1, v2: O2, v3: O3, scheduler: SchedulerLike): Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3>>;
/** @deprecated Use {@link scheduled} and {@link concatAll} (e.g. `scheduled([o1, o2, o3], scheduler).pipe(concatAll())`) */
export function concat<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>>(v1: O1, v2: O2, v3: O3, v4: O4, scheduler: SchedulerLike): Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3> | ObservedValueOf<O4>>;
/** @deprecated Use {@link scheduled} and {@link concatAll} (e.g. `scheduled([o1, o2, o3], scheduler).pipe(concatAll())`) */
export function concat<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, O5 extends ObservableInput<any>>(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, scheduler: SchedulerLike): Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3> | ObservedValueOf<O4> | ObservedValueOf<O5>>;
/** @deprecated Use {@link scheduled} and {@link concatAll} (e.g. `scheduled([o1, o2, o3], scheduler).pipe(concatAll())`) */
export function concat<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, O5 extends ObservableInput<any>, O6 extends ObservableInput<any>>(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, v6: O6, scheduler: SchedulerLike): Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3> | ObservedValueOf<O4> | ObservedValueOf<O5> | ObservedValueOf<O6>>;
export function concat<O1 extends ObservableInput<any>>(v1: O1): Observable<ObservedValueOf<O1>>;
export function concat<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>>(v1: O1, v2: O2): Observable<ObservedValueOf<O1> | ObservedValueOf<O2>>;
export function concat<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>>(v1: O1, v2: O2, v3: O3): Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3>>;
export function concat<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>>(v1: O1, v2: O2, v3: O3, v4: O4): Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3> | ObservedValueOf<O4>>;
export function concat<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, O5 extends ObservableInput<any>>(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5): Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3> | ObservedValueOf<O4> | ObservedValueOf<O5>>;
export function concat<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, O5 extends ObservableInput<any>, O6 extends ObservableInput<any>>(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, v6: O6): Observable<ObservedValueOf<O1> | ObservedValueOf<O2> | ObservedValueOf<O3> | ObservedValueOf<O4> | ObservedValueOf<O5> | ObservedValueOf<O6>>;
export function concat<O extends ObservableInput<any>>(...observables: O[]): Observable<ObservedValueOf<O>>;
/** @deprecated Use {@link scheduled} and {@link concatAll} (e.g. `scheduled([o1, o2, o3], scheduler).pipe(concatAll())`) */
export function concat<O extends ObservableInput<any>>(...observables: (O | SchedulerLike)[]): Observable<ObservedValueOf<O>>;
export function concat<R>(...observables: ObservableInput<any>[]): Observable<R>;
/** @deprecated Use {@link scheduled} and {@link concatAll} (e.g. `scheduled([o1, o2, o3], scheduler).pipe(concatAll())`) */
export function concat<R>(...observables: (ObservableInput<any> | SchedulerLike)[]): Observable<R>;
/* tslint:enable:max-line-length */
/**
* Creates an output Observable which sequentially emits all values from given
@@ -54,7 +71,10 @@ export function concat<T, R>(...observables: (ObservableInput<any> | SchedulerLi
*
* ## Examples
* ### Concatenate a timer counting from 0 to 3 with a synchronous sequence from 1 to 10
* ```javascript
* ```ts
* import { concat, interval, range } from 'rxjs';
* import { take } from 'rxjs/operators';
*
* const timer = interval(1000).pipe(take(4));
* const sequence = range(1, 10);
* const result = concat(timer, sequence);
@@ -64,12 +84,16 @@ export function concat<T, R>(...observables: (ObservableInput<any> | SchedulerLi
* // 0 -1000ms-> 1 -1000ms-> 2 -1000ms-> 3 -immediate-> 1 ... 10
* ```
*
* ### Concatenate an array of 3 Observables
* ```javascript
* ### Concatenate 3 Observables
* ```ts
* import { concat, interval } from 'rxjs';
* import { take } from 'rxjs/operators';
*
* const timer1 = interval(1000).pipe(take(10));
* const timer2 = interval(2000).pipe(take(6));
* const timer3 = interval(500).pipe(take(10));
* const result = concat([timer1, timer2, timer3]); // note that array is passed
*
* const result = concat(timer1, timer2, timer3);
* result.subscribe(x => console.log(x));
*
* // results in the following:
@@ -80,9 +104,12 @@ export function concat<T, R>(...observables: (ObservableInput<any> | SchedulerLi
* ```
*
* ### Concatenate the same Observable to repeat it
* ```javascript
* ```ts
* import { concat, interval } from 'rxjs';
* import { take } from 'rxjs/operators';
*
* const timer = interval(1000).pipe(take(2));
* *
*
* concat(timer, timer) // concatenating the same Observable!
* .subscribe(
* value => console.log(value),
@@ -113,9 +140,6 @@ export function concat<T, R>(...observables: (ObservableInput<any> | SchedulerLi
* @name concat
* @owner Observable
*/
export function concat<T, R>(...observables: Array<ObservableInput<any> | SchedulerLike>): Observable<R> {
if (observables.length === 1 || (observables.length === 2 && isScheduler(observables[1]))) {
return from(<any>observables[0]);
}
export function concat<O extends ObservableInput<any>, R>(...observables: Array<O | SchedulerLike>): Observable<ObservedValueOf<O> | R> {
return concatAll<R>()(of(...observables));
}
+8 -6
View File
@@ -1,5 +1,5 @@
import { Observable } from '../Observable';
import { SubscribableOrPromise } from '../types';
import { SubscribableOrPromise, ObservedValueOf, ObservableInput } from '../types';
import { from } from './from'; // lol
import { empty } from './empty';
@@ -23,7 +23,9 @@ import { empty } from './empty';
*
* ## Example
* ### Subscribe to either an Observable of clicks or an Observable of interval, at random
* ```javascript
* ```ts
* import { defer, fromEvent, interval } from 'rxjs';
*
* const clicksOrInterval = defer(function () {
* return Math.random() > 0.5
* ? fromEvent(document, 'click')
@@ -50,9 +52,9 @@ import { empty } from './empty';
* @name defer
* @owner Observable
*/
export function defer<T>(observableFactory: () => SubscribableOrPromise<T> | void): Observable<T> {
return new Observable(subscriber => {
let input: SubscribableOrPromise<T> | void;
export function defer<O extends ObservableInput<any>>(observableFactory: () => O | void): Observable<ObservedValueOf<O>> {
return new Observable<ObservedValueOf<O>>(subscriber => {
let input: O | void;
try {
input = observableFactory();
} catch (err) {
@@ -62,4 +64,4 @@ export function defer<T>(observableFactory: () => SubscribableOrPromise<T> | voi
const source = input ? from(input) : empty();
return source.subscribe(subscriber);
});
}
}
+56 -52
View File
@@ -1,6 +1,4 @@
import { root } from '../../util/root';
import { tryCatch } from '../../util/tryCatch';
import { errorObject } from '../../util/errorObject';
import { Observable } from '../../Observable';
import { Subscriber } from '../../Subscriber';
import { TeardownLogic } from '../../types';
@@ -111,9 +109,11 @@ export class AjaxObservable<T> extends Observable<T> {
* url, headers, etc or a string for a URL.
*
* ## Example
* ```javascript
* source = Rx.Observable.ajax('/products');
* source = Rx.Observable.ajax({ url: 'products', method: 'GET' });
* ```ts
* import { ajax } from 'rxjs/ajax';
*
* const source1 = ajax('/products');
* const source2 = ajax({ url: 'products', method: 'GET' });
* ```
*
* @param {string|Object} request Can be one of the following:
@@ -202,17 +202,18 @@ export class AjaxSubscriber<T> extends Subscriber<Event> {
const headers = request.headers = request.headers || {};
// force CORS if requested
if (!request.crossDomain && !headers['X-Requested-With']) {
if (!request.crossDomain && !this.getHeader(headers, 'X-Requested-With')) {
headers['X-Requested-With'] = 'XMLHttpRequest';
}
// ensure content type is set
if (!('Content-Type' in headers) && !(root.FormData && request.body instanceof root.FormData) && typeof request.body !== 'undefined') {
let contentTypeHeader = this.getHeader(headers, 'Content-Type');
if (!contentTypeHeader && !(root.FormData && request.body instanceof root.FormData) && typeof request.body !== 'undefined') {
headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
}
// properly serialize body
request.body = this.serializeBody(request.body, request.headers['Content-Type']);
request.body = this.serializeBody(request.body, this.getHeader(request.headers, 'Content-Type'));
this.send();
}
@@ -220,26 +221,22 @@ export class AjaxSubscriber<T> extends Subscriber<Event> {
next(e: Event): void {
this.done = true;
const { xhr, request, destination } = this;
const response = new AjaxResponse(e, xhr, request);
if (response.response === errorObject) {
destination.error(errorObject.e);
} else {
destination.next(response);
let result;
try {
result = new AjaxResponse(e, xhr, request);
} catch (err) {
return destination.error(err);
}
destination.next(result);
}
private send(): XMLHttpRequest {
private send(): void {
const {
request,
request: { user, method, url, async, password, headers, body }
} = this;
const createXHR = request.createXHR;
const xhr: XMLHttpRequest = tryCatch(createXHR).call(request);
if (<any>xhr === errorObject) {
this.error(errorObject.e);
} else {
this.xhr = xhr;
try {
const xhr = this.xhr = request.createXHR();
// set up the events before open XHR
// https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
@@ -247,16 +244,10 @@ export class AjaxSubscriber<T> extends Subscriber<Event> {
// Otherwise the progress events will not fire.
this.setupEvents(xhr, request);
// open XHR
let result: any;
if (user) {
result = tryCatch(xhr.open).call(xhr, method, url, async, user, password);
xhr.open(method, url, async, user, password);
} else {
result = tryCatch(xhr.open).call(xhr, method, url, async);
}
if (result === errorObject) {
this.error(errorObject.e);
return null;
xhr.open(method, url, async);
}
// timeout, responseType and withCredentials can be set once the XHR is open
@@ -273,14 +264,14 @@ export class AjaxSubscriber<T> extends Subscriber<Event> {
this.setHeaders(xhr, headers);
// finally send the request
result = body ? tryCatch(xhr.send).call(xhr, body) : tryCatch(xhr.send).call(xhr);
if (result === errorObject) {
this.error(errorObject.e);
return null;
if (body) {
xhr.send(body);
} else {
xhr.send();
}
} catch (err) {
this.error(err);
}
return xhr;
}
private serializeBody(body: any, contentType?: string) {
@@ -315,20 +306,31 @@ export class AjaxSubscriber<T> extends Subscriber<Event> {
}
}
private getHeader(headers: {}, headerName: string): any {
for (let key in headers) {
if (key.toLowerCase() === headerName.toLowerCase()) {
return headers[key];
}
}
return undefined;
}
private setupEvents(xhr: XMLHttpRequest, request: AjaxRequest) {
const progressSubscriber = request.progressSubscriber;
function xhrTimeout(this: XMLHttpRequest, e: ProgressEvent) {
function xhrTimeout(this: XMLHttpRequest, e: ProgressEvent): void {
const {subscriber, progressSubscriber, request } = (<any>xhrTimeout);
if (progressSubscriber) {
progressSubscriber.error(e);
}
const ajaxTimeoutError = new AjaxTimeoutError(this, request); //TODO: Make betterer.
if (ajaxTimeoutError.response === errorObject) {
subscriber.error(errorObject.e);
} else {
subscriber.error(ajaxTimeoutError);
let error;
try {
error = new AjaxTimeoutError(this, request); // TODO: Make betterer.
} catch (err) {
error = err;
}
subscriber.error(error);
}
xhr.ontimeout = xhrTimeout;
(<any>xhrTimeout).request = request;
@@ -354,12 +356,13 @@ export class AjaxSubscriber<T> extends Subscriber<Event> {
if (progressSubscriber) {
progressSubscriber.error(e);
}
const ajaxError = new AjaxError('ajax error', this, request);
if (ajaxError.response === errorObject) {
subscriber.error(errorObject.e);
} else {
subscriber.error(ajaxError);
let error;
try {
error = new AjaxError('ajax error', this, request);
} catch (err) {
error = err;
}
subscriber.error(error);
};
xhr.onerror = xhrError;
(<any>xhrError).request = request;
@@ -401,12 +404,13 @@ export class AjaxSubscriber<T> extends Subscriber<Event> {
if (progressSubscriber) {
progressSubscriber.error(e);
}
const ajaxError = new AjaxError('ajax error ' + status, this, request);
if (ajaxError.response === errorObject) {
subscriber.error(errorObject.e);
} else {
subscriber.error(ajaxError);
let error;
try {
error = new AjaxError('ajax error ' + status, this, request);
} catch (err) {
error = err;
}
subscriber.error(error);
}
}
}
@@ -512,7 +516,7 @@ function parseJson(xhr: XMLHttpRequest) {
function parseXhrResponse(responseType: string, xhr: XMLHttpRequest) {
switch (responseType) {
case 'json':
return tryCatch(parseJson)(xhr);
return parseJson(xhr);
case 'xml':
return xhr.responseXML;
case 'text':
+124 -40
View File
@@ -5,8 +5,97 @@ import { Subscription } from '../../Subscription';
import { Operator } from '../../Operator';
import { ReplaySubject } from '../../ReplaySubject';
import { Observer, NextObserver } from '../../types';
import { tryCatch } from '../../util/tryCatch';
import { errorObject } from '../../util/errorObject';
/**
* WebSocketSubjectConfig is a plain Object that allows us to make our
* webSocket configurable.
*
* <span class="informal">Provides flexibility to {@link webSocket}</span>
*
* It defines a set of properties to provide custom behavior in specific
* moments of the socket's lifecycle. When the connection opens we can
* use `openObserver`, when the connection is closed `closeObserver`, if we
* are interested in listening for data comming from server: `deserializer`,
* which allows us to customize the deserialization strategy of data before passing it
* to the socket client. By default `deserializer` is going to apply `JSON.parse` to each message comming
* from the Server.
*
* ## Example
* **deserializer**, the default for this property is `JSON.parse` but since there are just two options
* for incomming data, either be text or binarydata. We can apply a custom deserialization strategy
* or just simply skip the default behaviour.
* ```ts
* import { webSocket } from 'rxjs/webSocket';
*
* const wsSubject = webSocket({
* url: 'ws://localhost:8081',
* //Apply any transformation of your choice.
* deserializer: ({data}) => data
* });
*
* wsSubject.subscribe(console.log);
*
* // Let's suppose we have this on the Server: ws.send("This is a msg from the server")
* //output
* //
* // This is a msg from the server
* ```
*
* **serializer** allows us tom apply custom serialization strategy but for the outgoing messages
* ```ts
* import { webSocket } from 'rxjs/webSocket';
*
* const wsSubject = webSocket({
* url: 'ws://localhost:8081',
* //Apply any transformation of your choice.
* serializer: msg => JSON.stringify({channel: "webDevelopment", msg: msg})
* });
*
* wsSubject.subscribe(() => subject.next("msg to the server"));
*
* // Let's suppose we have this on the Server: ws.send("This is a msg from the server")
* //output
* //
* // {"channel":"webDevelopment","msg":"msg to the server"}
* ```
*
* **closeObserver** allows us to set a custom error when an error raise up.
* ```ts
* import { webSocket } from 'rxjs/webSocket';
*
* const wsSubject = webSocket({
* url: 'ws://localhost:8081',
* closeObserver: {
next(closeEvent) {
const customError = { code: 6666, reason: "Custom evil reason" }
console.log(`code: ${customError.code}, reason: ${customError.reason}`);
}
}
* });
*
* //output
* // code: 6666, reason: Custom evil reason
* ```
*
* **openObserver**, Let's say we need to make some kind of init task before sending/receiving msgs to the
* webSocket or sending notification that the connection was successful, this is when
* openObserver is usefull for.
* ```ts
* import { webSocket } from 'rxjs/webSocket';
*
* const wsSubject = webSocket({
* url: 'ws://localhost:8081',
* openObserver: {
* next: () => {
* console.log('connetion ok');
* }
* },
* });
*
* //output
* // connetion ok`
* ```
* */
export interface WebSocketSubjectConfig<T> {
/** The url of the socket server to connect to */
@@ -59,11 +148,6 @@ const WEBSOCKETSUBJECT_INVALID_ERROR_OBJECT =
export type WebSocketMessage = string | ArrayBuffer | Blob | ArrayBufferView;
/**
* We need this JSDoc comment for affecting ESDoc.
* @extends {Ignored}
* @hide true
*/
export class WebSocketSubject<T> extends AnonymousSubject<T> {
private _config: WebSocketSubjectConfig<T>;
@@ -136,30 +220,29 @@ export class WebSocketSubject<T> extends AnonymousSubject<T> {
multiplex(subMsg: () => any, unsubMsg: () => any, messageFilter: (value: T) => boolean) {
const self = this;
return new Observable((observer: Observer<any>) => {
const result = tryCatch(subMsg)();
if (result === errorObject) {
observer.error(errorObject.e);
} else {
self.next(result);
try {
self.next(subMsg());
} catch (err) {
observer.error(err);
}
let subscription = self.subscribe(x => {
const result = tryCatch(messageFilter)(x);
if (result === errorObject) {
observer.error(errorObject.e);
} else if (result) {
observer.next(x);
const subscription = self.subscribe(x => {
try {
if (messageFilter(x)) {
observer.next(x);
}
} catch (err) {
observer.error(err);
}
},
err => observer.error(err),
() => observer.complete());
return () => {
const result = tryCatch(unsubMsg)();
if (result === errorObject) {
observer.error(errorObject.e);
} else {
self.next(result);
try {
self.next(unsubMsg());
} catch (err) {
observer.error(err);
}
subscription.unsubscribe();
};
@@ -192,6 +275,12 @@ export class WebSocketSubject<T> extends AnonymousSubject<T> {
});
socket.onopen = (e: Event) => {
const { _socket } = this;
if (!_socket) {
socket.close();
this._resetState();
return;
}
const { openObserver } = this._config;
if (openObserver) {
openObserver.next(e);
@@ -202,13 +291,12 @@ export class WebSocketSubject<T> extends AnonymousSubject<T> {
this.destination = Subscriber.create<T>(
(x) => {
if (socket.readyState === 1) {
const { serializer } = this._config;
const msg = tryCatch(serializer)(x);
if (msg === errorObject) {
this.destination.error(errorObject.e);
return;
try {
const { serializer } = this._config;
socket.send(serializer(x));
} catch (e) {
this.destination.error(e);
}
socket.send(msg);
}
},
(e) => {
@@ -257,12 +345,11 @@ export class WebSocketSubject<T> extends AnonymousSubject<T> {
};
socket.onmessage = (e: MessageEvent) => {
const { deserializer } = this._config;
const result = tryCatch(deserializer)(e);
if (result === errorObject) {
observer.error(errorObject.e);
} else {
observer.next(result);
try {
const { deserializer } = this._config;
observer.next(deserializer(e));
} catch (err) {
observer.error(err);
}
};
}
@@ -290,14 +377,11 @@ export class WebSocketSubject<T> extends AnonymousSubject<T> {
}
unsubscribe() {
const { source, _socket } = this;
const { _socket } = this;
if (_socket && _socket.readyState === 1) {
_socket.close();
this._resetState();
}
this._resetState();
super.unsubscribe();
if (!source) {
this.destination = new ReplaySubject();
}
}
}
+68 -5
View File
@@ -5,15 +5,78 @@ import { AjaxObservable, AjaxCreationMethod } from './AjaxObservable';
* It creates an observable for an Ajax request with either a request object with
* url, headers, etc or a string for a URL.
*
* ## Using ajax.getJSON() to fetch data from API.
* ```javascript
*
* ## Using ajax() to fetch the response object that is being returned from API.
* ```ts
* import { ajax } from 'rxjs/ajax';
* import { map, catchError } from 'rxjs/operators';
* import { of } from 'rxjs';
*
* const obs$ = ajax(`https://api.github.com/users?per_page=5`).pipe(
* map(userResponse => console.log('users: ', userResponse)),
* catchError(error => {
* console.log('error: ', error);
* return of(error);
* })
* );
*
* ```
*
* ## Using ajax.getJSON() to fetch data from API.
* ```ts
* import { ajax } from 'rxjs/ajax';
* import { map, catchError } from 'rxjs/operators';
* import { of } from 'rxjs';
*
* const obs$ = ajax.getJSON(`https://api.github.com/users?per_page=5`).pipe(
* map(userResponse => console.log('users: ', userResponse)),
* catchError(error => console.log('error: ', error))
* ));
* catchError(error => {
* console.log('error: ', error);
* return of(error);
* })
* );
*
* ```
*
* ## Using ajax() with object as argument and method POST with a two seconds delay.
* ```ts
* import { ajax } from 'rxjs/ajax';
* import { of } from 'rxjs';
*
* const users = ajax({
* url: 'https://httpbin.org/delay/2',
* method: 'POST',
* headers: {
* 'Content-Type': 'application/json',
* 'rxjs-custom-header': 'Rxjs'
* },
* body: {
* rxjs: 'Hello World!'
* }
* }).pipe(
* map(response => console.log('response: ', response)),
* catchError(error => {
* console.log('error: ', error);
* return of(error);
* })
* );
*
* ```
*
* ## Using ajax() to fetch. An error object that is being returned from the request.
* ```ts
* import { ajax } from 'rxjs/ajax';
* import { map, catchError } from 'rxjs/operators';
* import { of } from 'rxjs';
*
* const obs$ = ajax(`https://api.github.com/404`).pipe(
* map(userResponse => console.log('users: ', userResponse)),
* catchError(error => {
* console.log('error: ', error);
* return of(error);
* })
* );
*
* ```
*/
export const ajax: AjaxCreationMethod = AjaxObservable.create;
export const ajax: AjaxCreationMethod = AjaxObservable.create;
+95
View File
@@ -0,0 +1,95 @@
import { Observable } from '../../Observable';
/**
* Uses [the Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) to
* make an HTTP request.
*
* **WARNING** Parts of the fetch API are still experimental. `AbortController` is
* required for this implementation to work and use cancellation appropriately.
*
* Will automatically set up an internal [AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController)
* in order to teardown the internal `fetch` when the subscription tears down.
*
* If a `signal` is provided via the `init` argument, it will behave like it usually does with
* `fetch`. If the provided `signal` aborts, the error that `fetch` normally rejects with
* in that scenario will be emitted as an error from the observable.
*
* ### Basic Use
*
* ```ts
* import { of } from 'rxjs';
* import { fromFetch } from 'rxjs/fetch';
* import { switchMap, catchError } from 'rxjs/operators';
*
* const data$ = fromFetch('https://api.github.com/users?per_page=5').pipe(
* switchMap(response => {
* if (response.ok) {
* // OK return data
* return response.json();
* } else {
* // Server is returning a status requiring the client to try something else.
* return of({ error: true, message: `Error ${response.status}` });
* }
* }),
* catchError(err => {
* // Network or other error, handle appropriately
* console.error(err);
* return of({ error: true, message: err.message })
* })
* );
*
* data$.subscribe({
* next: result => console.log(result),
* complete: () => console.log('done')
* })
* ```
*
* @param input The resource you would like to fetch. Can be a url or a request object.
* @param init A configuration object for the fetch.
* [See MDN for more details](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters)
* @returns An Observable, that when subscribed to performs an HTTP request using the native `fetch`
* function. The {@link Subscription} is tied to an `AbortController` for the the fetch.
*/
export function fromFetch(input: string | Request, init?: RequestInit): Observable<Response> {
return new Observable<Response>(subscriber => {
const controller = new AbortController();
const signal = controller.signal;
let outerSignalHandler: () => void;
let abortable = true;
let unsubscribed = false;
if (init) {
// If a signal is provided, just have it teardown. It's a cancellation token, basically.
if (init.signal) {
outerSignalHandler = () => {
if (!signal.aborted) {
controller.abort();
}
};
init.signal.addEventListener('abort', outerSignalHandler);
}
init.signal = signal;
} else {
init = { signal };
}
fetch(input, init).then(response => {
abortable = false;
subscriber.next(response);
subscriber.complete();
}).catch(err => {
abortable = false;
if (!unsubscribed) {
// Only forward the error if it wasn't an abort.
subscriber.error(err);
}
});
return () => {
unsubscribed = true;
if (abortable) {
controller.abort();
}
};
});
}
+37 -40
View File
@@ -66,16 +66,17 @@ import { WebSocketSubject, WebSocketSubjectConfig } from './WebSocketSubject';
* subscribes and unsubscribes. Server can use them to verify that some kind of messages should start or stop
* being forwarded to the client. In case of the above example application, after getting subscription message with proper identifier,
* gateway server can decide that it should connect to real sport news service and start forwarding messages from it.
* Note that both messages will be sent as returned by the functions, meaning they will have to be serialized manually, just
* Note that both messages will be sent as returned by the functions, they are by default serialized using JSON.stringify, just
* as messages pushed via `next`. Also bear in mind that these messages will be sent on *every* subscription and
* unsubscription. This is potentially dangerous, because one consumer of an Observable may unsubscribe and the server
* might stop sending messages, since it got unsubscription message. This needs to be handled
* on the server or using {@link publish} on a Observable returned from 'multiplex'.
*
* Last argument to `multiplex` is a `messageFilter` function which filters out messages
* Last argument to `multiplex` is a `messageFilter` function which should return a boolean. It is used to filter out messages
* sent by the server to only those that belong to simulated WebSocket stream. For example, server might mark these
* messages with some kind of string identifier on a message object and `messageFilter` would return `true`
* if there is such identifier on an object emitted by the socket.
* if there is such identifier on an object emitted by the socket. Messages which returns `false` in `messageFilter` are simply skipped,
* and are not passed down the stream.
*
* Return value of `multiplex` is an Observable with messages incoming from emulated socket connection. Note that this
* is not a `WebSocketSubject`, so calling `next` or `multiplex` again will fail. For pushing values to the
@@ -83,71 +84,67 @@ import { WebSocketSubject, WebSocketSubjectConfig } from './WebSocketSubject';
*
* ### Examples
* #### Listening for messages from the server
* const subject = Rx.Observable.webSocket('ws://localhost:8081');
* ```ts
* import { webSocket } from "rxjs/webSocket";
* const subject = webSocket("ws://localhost:8081");
*
* subject.subscribe(
* (msg) => console.log('message received: ' + msg), // Called whenever there is a message from the server.
* (err) => console.log(err), // Called if at any point WebSocket API signals some kind of error.
* msg => console.log('message received: ' + msg), // Called whenever there is a message from the server.
* err => console.log(err), // Called if at any point WebSocket API signals some kind of error.
* () => console.log('complete') // Called when connection is closed (for whatever reason).
* );
*
* ```
*
* #### Pushing messages to the server
* const subject = Rx.Observable.webSocket('ws://localhost:8081');
* ```ts
* import { webSocket } from "rxjs/webSocket";
* const subject = webSocket('ws://localhost:8081');
*
* subject.subscribe(); // Note that at least one consumer has to subscribe to
* // the created subject - otherwise "nexted" values will be just
* // buffered and not sent, since no connection was established!
* subject.subscribe();
* // Note that at least one consumer has to subscribe to the created subject - otherwise "nexted" values will be just buffered and not sent,
* // since no connection was established!
*
* subject.next(JSON.stringify({message: 'some message'})); // This will send a message to the server
* // once a connection is made.
* // Remember to serialize sent value first!
* subject.next({message: 'some message'});
* // This will send a message to the server once a connection is made. Remember value is serialized with JSON.stringify by default!
*
* subject.complete(); // Closes the connection.
*
*
* subject.error({code: 4000, reason: 'I think our app just broke!'}); // Also closes the connection,
* // but let's the server know that
* // this closing is caused by some error.
*
* subject.error({code: 4000, reason: 'I think our app just broke!'});
* // Also closes the connection, but let's the server know that this closing is caused by some error.
* ```
*
* #### Multiplexing WebSocket
* const subject = Rx.Observable.webSocket('ws://localhost:8081');
* ```ts
* import { webSocket } from "rxjs/webSocket";
* const subject = webSocket('ws://localhost:8081');
*
* const observableA = subject.multiplex(
* () => JSON.stringify({subscribe: 'A'}), // When server gets this message, it will start sending messages for 'A'...
* () => JSON.stringify({unsubscribe: 'A'}), // ...and when gets this one, it will stop.
* message => message.type === 'A' // Server will tag all messages for 'A' with type property.
* () => ({subscribe: 'A'}), // When server gets this message, it will start sending messages for 'A'...
* () => ({unsubscribe: 'A'}), // ...and when gets this one, it will stop.
* message => message.type === 'A' // If the function returns `true` message is passed down the stream. Skipped if the function returns false.
* );
*
* const observableB = subject.multiplex( // And the same goes for 'B'.
* () => JSON.stringify({subscribe: 'B'}),
* () => JSON.stringify({unsubscribe: 'B'}),
* () => ({subscribe: 'B'}),
* () => ({unsubscribe: 'B'}),
* message => message.type === 'B'
* );
*
* const subA = observableA.subscribe(messageForA => console.log(messageForA));
* // At this moment WebSocket connection
* // is established. Server gets '{"subscribe": "A"}'
* // message and starts sending messages for 'A',
* // At this moment WebSocket connection is established. Server gets '{"subscribe": "A"}' message and starts sending messages for 'A',
* // which we log here.
*
* const subB = observableB.subscribe(messageForB => console.log(messageForB));
* // Since we already have a connection,
* // we just send '{"subscribe": "B"}' message
* // to the server. It starts sending
* // messages for 'B', which we log here.
* // Since we already have a connection, we just send '{"subscribe": "B"}' message to the server. It starts sending messages for 'B',
* // which we log here.
*
* subB.unsubscribe();
* // Message '{"unsubscribe": "B"}' is sent to the
* // server, which stops sending 'B' messages.
*
* subA.unubscribe();
* // Message '{"unsubscribe": "A"}' makes the server
* // stop sending messages for 'A'. Since there is
* // no more subscribers to root Subject, socket
* // connection closes.
* // Message '{"unsubscribe": "B"}' is sent to the server, which stops sending 'B' messages.
*
* subA.unsubscribe();
* // Message '{"unsubscribe": "A"}' makes the server stop sending messages for 'A'. Since there is no more subscribers to root Subject,
* // socket connection closes.
* ```
*
*
* @param {string|WebSocketSubjectConfig} urlConfigOrSource The WebSocket endpoint as an url or an object with
+12 -9
View File
@@ -22,13 +22,19 @@ export const EMPTY = new Observable<never>(subscriber => subscriber.complete());
*
* ## Examples
* ### Emit the number 7, then complete
* ```javascript
* ```ts
* import { empty } from 'rxjs';
* import { startWith } from 'rxjs/operators';
*
* const result = empty().pipe(startWith(7));
* result.subscribe(x => console.log(x));
* ```
*
* ### Map and flatten only odd numbers to the sequence 'a', 'b', 'c'
* ```javascript
* ```ts
* import { empty, interval } from 'rxjs';
* import { mergeMap } from 'rxjs/operators';
*
* const interval$ = interval(1000);
* result = interval$.pipe(
* mergeMap(x => x % 2 === 1 ? of('a', 'b', 'c') : empty()),
@@ -47,19 +53,16 @@ export const EMPTY = new Observable<never>(subscriber => subscriber.complete());
* @see {@link of}
* @see {@link throwError}
*
* @param {SchedulerLike} [scheduler] A {@link SchedulerLike} to use for scheduling
* @param scheduler A {@link SchedulerLike} to use for scheduling
* the emission of the complete notification.
* @return {Observable} An "empty" Observable: emits only the complete
* @return An "empty" Observable: emits only the complete
* notification.
* @static true
* @name empty
* @owner Observable
* @deprecated Deprecated in favor of using {@link index/EMPTY} constant.
* @deprecated Deprecated in favor of using {@link EMPTY} constant, or {@link scheduled} (e.g. `scheduled([], scheduler)`)
*/
export function empty(scheduler?: SchedulerLike) {
return scheduler ? emptyScheduled(scheduler) : EMPTY;
}
export function emptyScheduled(scheduler: SchedulerLike) {
function emptyScheduled(scheduler: SchedulerLike) {
return new Observable<never>(subscriber => scheduler.schedule(() => subscriber.complete()));
}
+137 -164
View File
@@ -1,131 +1,130 @@
import { Observable } from '../Observable';
import { ObservableInput } from '../types';
import { ObservableInput, ObservedValuesFromArray, ObservedValueOf, SubscribableOrPromise } from '../types';
import { isArray } from '../util/isArray';
import { EMPTY } from './empty';
import { subscribeToResult } from '../util/subscribeToResult';
import { OuterSubscriber } from '../OuterSubscriber';
import { InnerSubscriber } from '../InnerSubscriber';
import { Subscriber } from '../Subscriber';
import { map } from '../operators/map';
import { isObject } from '../util/isObject';
import { isObservable } from '../util/isObservable';
import { from } from './from';
/* tslint:disable:max-line-length */
// forkJoin([a$, b$, c$]);
export function forkJoin<T>(sources: [ObservableInput<T>]): Observable<T[]>;
export function forkJoin<T, T2>(sources: [ObservableInput<T>, ObservableInput<T2>]): Observable<[T, T2]>;
export function forkJoin<T, T2, T3>(sources: [ObservableInput<T>, ObservableInput<T2>, ObservableInput<T3>]): Observable<[T, T2, T3]>;
export function forkJoin<T, T2, T3, T4>(sources: [ObservableInput<T>, ObservableInput<T2>, ObservableInput<T3>, ObservableInput<T4>]): Observable<[T, T2, T3, T4]>;
export function forkJoin<T, T2, T3, T4, T5>(sources: [ObservableInput<T>, ObservableInput<T2>, ObservableInput<T3>, ObservableInput<T4>, ObservableInput<T5>]): Observable<[T, T2, T3, T4, T5]>;
export function forkJoin<T, T2, T3, T4, T5, T6>(sources: [ObservableInput<T>, ObservableInput<T2>, ObservableInput<T3>, ObservableInput<T4>, ObservableInput<T5>, ObservableInput<T6>]): Observable<[T, T2, T3, T4, T5, T6]>;
export function forkJoin<T>(sources: Array<ObservableInput<T>>): Observable<T[]>;
// forkJoin(a$, b$, c$)
export function forkJoin<T>(v1: ObservableInput<T>): Observable<T[]>;
/** @deprecated Use the version that takes an array of Observables instead */
export function forkJoin<T>(v1: SubscribableOrPromise<T>): Observable<[T]>;
/** @deprecated Use the version that takes an array of Observables instead */
export function forkJoin<T, T2>(v1: ObservableInput<T>, v2: ObservableInput<T2>): Observable<[T, T2]>;
/** @deprecated Use the version that takes an array of Observables instead */
export function forkJoin<T, T2, T3>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>): Observable<[T, T2, T3]>;
/** @deprecated Use the version that takes an array of Observables instead */
export function forkJoin<T, T2, T3, T4>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>): Observable<[T, T2, T3, T4]>;
/** @deprecated Use the version that takes an array of Observables instead */
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]>;
/** @deprecated Use the version that takes an array of Observables instead */
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]>;
// forkJoin([a$, b$, c$]);
// TODO(benlesh): Uncomment for TS 3.0
// export function forkJoin(sources: []): Observable<never>;
export function forkJoin<A>(sources: [ObservableInput<A>]): Observable<[A]>;
export function forkJoin<A, B>(sources: [ObservableInput<A>, ObservableInput<B>]): Observable<[A, B]>;
export function forkJoin<A, B, C>(sources: [ObservableInput<A>, ObservableInput<B>, ObservableInput<C>]): Observable<[A, B, C]>;
export function forkJoin<A, B, C, D>(sources: [ObservableInput<A>, ObservableInput<B>, ObservableInput<C>, ObservableInput<D>]): Observable<[A, B, C, D]>;
export function forkJoin<A, B, C, D, E>(sources: [ObservableInput<A>, ObservableInput<B>, ObservableInput<C>, ObservableInput<D>, ObservableInput<E>]): Observable<[A, B, C, D, E]>;
export function forkJoin<A, B, C, D, E, F>(sources: [ObservableInput<A>, ObservableInput<B>, ObservableInput<C>, ObservableInput<D>, ObservableInput<E>, ObservableInput<F>]): Observable<[A, B, C, D, E, F]>;
export function forkJoin<A extends ObservableInput<any>[]>(sources: A): Observable<ObservedValuesFromArray<A>[]>;
// forkJoin({})
export function forkJoin(sourcesObject: {}): Observable<never>;
export function forkJoin<T, K extends keyof T>(sourcesObject: T): Observable<{ [K in keyof T]: ObservedValueOf<T[K]> }>;
/** @deprecated resultSelector is deprecated, pipe to map instead */
export function forkJoin(...args: Array<ObservableInput<any>|Function>): Observable<any>;
/** @deprecated Use the version that takes an array of Observables instead */
export function forkJoin<T>(...sources: ObservableInput<T>[]): Observable<T[]>;
/* tslint:enable:max-line-length */
/**
* Joins last values emitted by passed Observables.
* Accepts an `Array` of {@link ObservableInput} or a dictionary `Object` of {@link ObservableInput} and returns
* an {@link Observable} that emits either an array of values in the exact same order as the passed array,
* or a dictionary of values in the same shape as the passed dictionary.
*
* <span class="informal">Wait for Observables to complete and then combine last values they emitted.</span>
*
* ![](forkJoin.png)
*
* `forkJoin` is an operator that takes any number of Observables which can be passed either as an array
* or directly as arguments. If no input Observables are provided, resulting stream will complete
* `forkJoin` is an operator that takes any number of input observables which can be passed either as an array
* or a dictionary of input observables. If no input observables are provided, resulting stream will complete
* immediately.
*
* `forkJoin` will wait for all passed Observables to complete and then it will emit an array with last
* values from corresponding Observables. So if you pass `n` Observables to the operator, resulting
* array will have `n` values, where first value is the last thing emitted by the first Observable,
* second value is the last thing emitted by the second Observable and so on. That means `forkJoin` will
* not emit more than once and it will complete after that. If you need to emit combined values not only
* at the end of lifecycle of passed Observables, but also throughout it, try out {@link combineLatest}
* `forkJoin` will wait for all passed observables to complete and then it will emit an array or an object with last
* values from corresponding observables.
*
* If you pass an array of `n` observables to the operator, resulting
* array will have `n` values, where first value is the last thing emitted by the first observable,
* second value is the last thing emitted by the second observable and so on.
*
* If you pass a dictionary of observables to the operator, resulting
* objects will have the same keys as the dictionary passed, with their last values they've emitted
* located at the corresponding key.
*
* That means `forkJoin` will not emit more than once and it will complete after that. If you need to emit combined
* values not only at the end of lifecycle of passed observables, but also throughout it, try out {@link combineLatest}
* or {@link zip} instead.
*
* In order for resulting array to have the same length as the number of input Observables, whenever any of
* that Observables completes without emitting any value, `forkJoin` will complete at that moment as well
* and it will not emit anything either, even if it already has some last values from other Observables.
* Conversely, if there is an Observable that never completes, `forkJoin` will never complete as well,
* unless at any point some other Observable completes without emitting value, which brings us back to
* the previous case. Overall, in order for `forkJoin` to emit a value, all Observables passed as arguments
* In order for resulting array to have the same length as the number of input observables, whenever any of
* that observables completes without emitting any value, `forkJoin` will complete at that moment as well
* and it will not emit anything either, even if it already has some last values from other observables.
* Conversely, if there is an observable that never completes, `forkJoin` will never complete as well,
* unless at any point some other observable completes without emitting value, which brings us back to
* the previous case. Overall, in order for `forkJoin` to emit a value, all observables passed as arguments
* have to emit something at least once and complete.
*
* If any input Observable errors at some point, `forkJoin` will error as well and all other Observables
* If any input observable errors at some point, `forkJoin` will error as well and all other observables
* will be immediately unsubscribed.
*
* Optionally `forkJoin` accepts project function, that will be called with values which normally
* would land in emitted array. Whatever is returned by project function, will appear in output
* Observable instead. This means that default project can be thought of as a function that takes
* observable instead. This means that default project can be thought of as a function that takes
* all its arguments and puts them into an array. Note that project function will be called only
* when output Observable is supposed to emit a result.
* when output observable is supposed to emit a result.
*
* ## Examples
* ### Use forkJoin with operator emitting immediately
* ```javascript
* import { forkJoin, of } from 'rxjs';
*
* const observable = forkJoin(
* of(1, 2, 3, 4),
* of(5, 6, 7, 8),
* );
* observable.subscribe(
* value => console.log(value),
* err => {},
* () => console.log('This is how it ends!'),
* );
* ### Use forkJoin with a dictionary of observable inputs
* ```ts
* import { forkJoin, of, timer } from 'rxjs';
*
* const observable = forkJoin({
* foo: of(1, 2, 3, 4),
* bar: Promise.resolve(8),
* baz: timer(4000),
* });
* observable.subscribe({
* next: value => console.log(value),
* complete: () => console.log('This is how it ends!'),
* });
*
* // Logs:
* // [4, 8]
* // "This is how it ends!"
* ```
*
* ### Use forkJoin with operator emitting after some time
* ```javascript
* import { forkJoin, interval } from 'rxjs';
* import { take } from 'rxjs/operators';
*
* const observable = forkJoin(
* interval(1000).pipe(take(3)), // emit 0, 1, 2 every second and complete
* interval(500).pipe(take(4)), // emit 0, 1, 2, 3 every half a second and complete
* );
* observable.subscribe(
* value => console.log(value),
* err => {},
* () => console.log('This is how it ends!'),
* );
*
* // Logs:
* // [2, 3] after 3 seconds
* // { foo: 4, bar: 8, baz: 0 } after 4 seconds
* // "This is how it ends!" immediately after
* ```
*
* ### Use forkJoin with project function
* ```javascript
* import { forkJoin, interval } from 'rxjs';
* import { take } from 'rxjs/operators';
* ### Use forkJoin with an array of observable inputs
* ```ts
* import { forkJoin, of } from 'rxjs';
*
* const observable = forkJoin(
* interval(1000).pipe(take(3)), // emit 0, 1, 2 every second and complete
* interval(500).pipe(take(4)), // emit 0, 1, 2, 3 every half a second and complete
* ).pipe(
* map(([n, m]) => n + m),
* );
* observable.subscribe(
* value => console.log(value),
* err => {},
* () => console.log('This is how it ends!'),
* );
* const observable = forkJoin([
* of(1, 2, 3, 4),
* Promise.resolve(8),
* timer(4000),
* ]);
* observable.subscribe({
* next: value => console.log(value),
* complete: () => console.log('This is how it ends!'),
* });
*
* // Logs:
* // 5 after 3 seconds
* // [4, 8, 0] after 4 seconds
* // "This is how it ends!" immediately after
* ```
*
@@ -139,93 +138,67 @@ export function forkJoin<T>(...sources: ObservableInput<T>[]): Observable<T[]>;
* @return {Observable} Observable emitting either an array of last values emitted by passed Observables
* or value from project function.
*/
export function forkJoin<T>(
...sources: Array<ObservableInput<T> | ObservableInput<T>[] | Function>
): Observable<T[]> {
export function forkJoin(
...sources: any[]
): Observable<any> {
if (sources.length === 1) {
const first = sources[0];
if (isArray(first)) {
return forkJoinInternal(first, null);
}
// TODO(benlesh): isObservable check will not be necessary when deprecated path is removed.
if (isObject(first) && Object.getPrototypeOf(first) === Object.prototype) {
const keys = Object.keys(first);
return forkJoinInternal(keys.map(key => first[key]), keys);
}
}
let resultSelector: Function;
// DEPRECATED PATHS BELOW HERE
if (typeof sources[sources.length - 1] === 'function') {
// DEPRECATED PATH
resultSelector = sources.pop() as Function;
}
// 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>>;
}
if (sources.length === 0) {
return EMPTY;
}
if (resultSelector) {
// DEPRECATED PATH
return forkJoin(sources).pipe(
map(args => resultSelector(...args))
const resultSelector = sources.pop() as Function;
sources = (sources.length === 1 && isArray(sources[0])) ? sources[0] : sources;
return forkJoinInternal(sources, null).pipe(
map((args: any[]) => resultSelector(...args))
);
}
return forkJoinInternal(sources, null);
}
function forkJoinInternal(sources: ObservableInput<any>[], keys: string[] | null): Observable<any> {
return new Observable(subscriber => {
return new ForkJoinSubscriber(subscriber, sources as Array<ObservableInput<T>>);
const len = sources.length;
if (len === 0) {
subscriber.complete();
return;
}
const values = new Array(len);
let completed = 0;
let emitted = 0;
for (let i = 0; i < len; i++) {
const source = from(sources[i]);
let hasValue = false;
subscriber.add(source.subscribe({
next: value => {
if (!hasValue) {
hasValue = true;
emitted++;
}
values[i] = value;
},
error: err => subscriber.error(err),
complete: () => {
completed++;
if (completed === len || !hasValue) {
if (emitted === len) {
subscriber.next(keys ?
keys.reduce((result, key, i) => (result[key] = values[i], result), {}) :
values);
}
subscriber.complete();
}
}
}));
}
});
}
/**
* We need this JSDoc comment for affecting ESDoc.
* @ignore
* @extends {Ignored}
*/
class ForkJoinSubscriber<T, R> extends OuterSubscriber<T, T> {
private completed = 0;
private values: T[];
private haveValues = 0;
constructor(destination: Subscriber<R>,
private sources: Array<ObservableInput<T>>) {
super(destination);
const len = sources.length;
this.values = new Array(len);
for (let i = 0; i < len; i++) {
const source = sources[i];
const innerSubscription = subscribeToResult(this, source, null, i);
if (innerSubscription) {
this.add(innerSubscription);
}
}
}
notifyNext(outerValue: any, innerValue: T,
outerIndex: number, innerIndex: number,
innerSub: InnerSubscriber<T, T>): void {
this.values[outerIndex] = innerValue;
if (!(innerSub as any)._hasValue) {
(innerSub as any)._hasValue = true;
this.haveValues++;
}
}
notifyComplete(innerSub: InnerSubscriber<T, T>): void {
const { destination, haveValues, values } = this;
const len = values.length;
if (!(innerSub as any)._hasValue) {
destination.complete();
return;
}
this.completed++;
if (this.completed !== len) {
return;
}
if (haveValues === len) {
destination.next(values);
}
destination.complete();
}
}
+37 -39
View File
@@ -1,17 +1,11 @@
import { Observable } from '../Observable';
import { isPromise } from '../util/isPromise';
import { isArrayLike } from '../util/isArrayLike';
import { isInteropObservable } from '../util/isInteropObservable';
import { isIterable } from '../util/isIterable';
import { fromArray } from './fromArray';
import { fromPromise } from './fromPromise';
import { fromIterable } from './fromIterable';
import { fromObservable } from './fromObservable';
import { subscribeTo } from '../util/subscribeTo';
import { ObservableInput, SchedulerLike } from '../types';
import { ObservableInput, SchedulerLike, ObservedValueOf } from '../types';
import { scheduled } from '../scheduled/scheduled';
export function from<T>(input: ObservableInput<T>, scheduler?: SchedulerLike): Observable<T>;
export function from<T>(input: ObservableInput<ObservableInput<T>>, scheduler?: SchedulerLike): Observable<Observable<T>>;
export function from<O extends ObservableInput<any>>(input: O): Observable<ObservedValueOf<O>>;
/** @deprecated use {@link scheduled} instead. */
export function from<O extends ObservableInput<any>>(input: O, scheduler: SchedulerLike): Observable<ObservedValueOf<O>>;
/**
* Creates an Observable from an Array, an array-like object, a Promise, an iterable object, or an Observable-like object.
@@ -27,9 +21,11 @@ export function from<T>(input: ObservableInput<ObservableInput<T>>, scheduler?:
* converted through this operator.
*
* ## Examples
*
* ### Converts an array to an Observable
* ```javascript
* import { from } from 'rxjs/observable/from';
*
* ```ts
* import { from } from 'rxjs';
*
* const array = [10, 20, 30];
* const result = from(array);
@@ -37,15 +33,18 @@ export function from<T>(input: ObservableInput<ObservableInput<T>>, scheduler?:
* result.subscribe(x => console.log(x));
*
* // Logs:
* // 10 20 30
* // 10
* // 20
* // 30
* ```
*
* ---
*
* ### Convert an infinite iterable (from a generator) to an Observable
* ```javascript
*
* ```ts
* import { from } from 'rxjs';
* import { take } from 'rxjs/operators';
* import { from } from 'rxjs/observable/from';
*
* function* generateDoubles(seed) {
* let i = seed;
@@ -61,32 +60,44 @@ export function from<T>(input: ObservableInput<ObservableInput<T>>, scheduler?:
* result.subscribe(x => console.log(x));
*
* // Logs:
* // 3 6 12 24 48 96 192 384 768 1536
* // 3
* // 6
* // 12
* // 24
* // 48
* // 96
* // 192
* // 384
* // 768
* // 1536
* ```
*
* ---
*
* ### with async scheduler
* ```javascript
* import { from } from 'rxjs/observable/from';
* import { async } from 'rxjs/scheduler/async';
* ### With async scheduler
*
* ```ts
* import { from, asyncScheduler } from 'rxjs';
*
* console.log('start');
*
* const array = [10, 20, 30];
* const result = from(array, async);
* const result = from(array, asyncScheduler);
*
* result.subscribe(x => console.log(x));
*
* console.log('end');
*
* // Logs:
* // start end 10 20 30
* // start
* // end
* // 10
* // 20
* // 30
* ```
*
* @see {@link fromEvent}
* @see {@link fromEventPattern}
* @see {@link fromPromise}
*
* @param {ObservableInput<T>} A subscription object, a Promise, an Observable-like,
* an Array, an iterable, or an array-like object to be converted.
@@ -95,26 +106,13 @@ export function from<T>(input: ObservableInput<ObservableInput<T>>, scheduler?:
* @name from
* @owner Observable
*/
export function from<T>(input: ObservableInput<T>, scheduler?: SchedulerLike): Observable<T> {
if (!scheduler) {
if (input instanceof Observable) {
return input;
}
return new Observable<T>(subscribeTo(input));
} else {
return scheduled(input, scheduler);
}
if (input != null) {
if (isInteropObservable(input)) {
return fromObservable(input, scheduler);
} else if (isPromise(input)) {
return fromPromise(input, scheduler);
} else if (isArrayLike(input)) {
return fromArray(input, scheduler);
} else if (isIterable(input) || typeof input === 'string') {
return fromIterable(input, scheduler);
}
}
throw new TypeError((input !== null && typeof input || input) + ' is not observable');
}
+2 -16
View File
@@ -1,26 +1,12 @@
import { Observable } from '../Observable';
import { SchedulerLike } from '../types';
import { Subscription } from '../Subscription';
import { subscribeToArray } from '../util/subscribeToArray';
import { scheduleArray } from '../scheduled/scheduleArray';
export function fromArray<T>(input: ArrayLike<T>, scheduler?: SchedulerLike) {
if (!scheduler) {
return new Observable<T>(subscribeToArray(input));
} else {
return new Observable<T>(subscriber => {
const sub = new Subscription();
let i = 0;
sub.add(scheduler.schedule(function () {
if (i === input.length) {
subscriber.complete();
return;
}
subscriber.next(input[i++]);
if (!subscriber.closed) {
sub.add(this.schedule());
}
}));
return sub;
});
return scheduleArray(input, scheduler);
}
}
+6 -2
View File
@@ -132,7 +132,9 @@ export function fromEvent<T>(target: FromEventTarget<T>, eventName: string, opti
*
* ## Examples
* ### Emits clicks happening on the DOM document
* ```javascript
* ```ts
* import { fromEvent } from 'rxjs';
*
* const clicks = fromEvent(document, 'click');
* clicks.subscribe(x => console.log(x));
*
@@ -142,7 +144,9 @@ export function fromEvent<T>(target: FromEventTarget<T>, eventName: string, opti
* ```
*
* ### Use addEventListener with capture option
* ```javascript
* ```ts
* import { fromEvent } from 'rxjs';
*
* const clicksInDocument = fromEvent(document, 'click', true); // note optional configuration parameter
* // which will be passed to addEventListener
* const clicksInDiv = fromEvent(someDivInDocument, 'click');
+14 -8
View File
@@ -1,13 +1,13 @@
import { Observable } from '../Observable';
import { isArray } from '../util/isArray';
import { isFunction } from '../util/isFunction';
import { fromEvent } from './fromEvent';
import { NodeEventHandler } from './fromEvent';
import { map } from '../operators/map';
/* tslint:disable:max-line-length */
export function fromEventPattern<T>(addHandler: (handler: Function) => any, removeHandler?: (handler: Function, signal?: any) => void): Observable<T>;
export function fromEventPattern<T>(addHandler: (handler: NodeEventHandler) => any, removeHandler?: (handler: NodeEventHandler, signal?: any) => void): Observable<T>;
/** @deprecated resultSelector no longer supported, pipe to map instead */
export function fromEventPattern<T>(addHandler: (handler: Function) => any, removeHandler?: (handler: Function, signal?: any) => void, resultSelector?: (...args: any[]) => T): Observable<T>;
export function fromEventPattern<T>(addHandler: (handler: NodeEventHandler) => any, removeHandler?: (handler: NodeEventHandler, signal?: any) => void, resultSelector?: (...args: any[]) => T): Observable<T>;
/* tslint:enable:max-line-length */
/**
@@ -58,7 +58,9 @@ export function fromEventPattern<T>(addHandler: (handler: Function) => any, remo
* ## Example
* ### Emits clicks happening on the DOM document
*
* ```javascript
* ```ts
* import { fromEventPattern } from 'rxjs';
*
* function addClickHandler(handler) {
* document.addEventListener('click', handler);
* }
@@ -80,7 +82,9 @@ export function fromEventPattern<T>(addHandler: (handler: Function) => any, remo
* ## Example
* ### Use with API that returns cancellation token
*
* ```javascript
* ```ts
* import { fromEventPattern } from 'rxjs';
*
* const token = someAPI.registerEventHandler(function() {});
* someAPI.unregisterEventHandler(token); // this APIs cancellation method accepts
* // not handler itself, but special token.
@@ -94,7 +98,9 @@ export function fromEventPattern<T>(addHandler: (handler: Function) => any, remo
* ## Example
* ### Use with project function
*
* ```javascript
* ```ts
* import { fromEventPattern } from 'rxjs';
*
* someAPI.registerEventHandler((eventType, eventMessage) => {
* console.log(eventType, eventMessage); // Logs "EVENT_TYPE" "EVENT_MESSAGE" to console.
* });
@@ -132,8 +138,8 @@ export function fromEventPattern<T>(addHandler: (handler: Function) => any, remo
* @owner Observable
*/
export function fromEventPattern<T>(addHandler: (handler: Function) => any,
removeHandler?: (handler: Function, signal?: any) => void,
export function fromEventPattern<T>(addHandler: (handler: NodeEventHandler) => any,
removeHandler?: (handler: NodeEventHandler, signal?: any) => void,
resultSelector?: (...args: any[]) => T): Observable<T | T[]> {
if (resultSelector) {
+3 -38
View File
@@ -1,50 +1,15 @@
import { Observable } from '../Observable';
import { SchedulerLike } from '../types';
import { Subscription } from '../Subscription';
import { iterator as Symbol_iterator } from '../symbol/iterator';
import { subscribeToIterable } from '../util/subscribeToIterable';
import { scheduleIterable } from '../scheduled/scheduleIterable';
export function fromIterable<T>(input: Iterable<T>, scheduler: SchedulerLike) {
export function fromIterable<T>(input: Iterable<T>, scheduler?: SchedulerLike) {
if (!input) {
throw new Error('Iterable cannot be null');
}
if (!scheduler) {
return new Observable<T>(subscribeToIterable(input));
} else {
return new Observable<T>(subscriber => {
const sub = new Subscription();
let iterator: Iterator<T>;
sub.add(() => {
// Finalize generators
if (iterator && typeof iterator.return === 'function') {
iterator.return();
}
});
sub.add(scheduler.schedule(() => {
iterator = input[Symbol_iterator]();
sub.add(scheduler.schedule(function () {
if (subscriber.closed) {
return;
}
let value: T;
let done: boolean;
try {
const result = iterator.next();
value = result.value;
done = result.done;
} catch (err) {
subscriber.error(err);
return;
}
if (done) {
subscriber.complete();
} else {
subscriber.next(value);
this.schedule();
}
}));
}));
return sub;
});
return scheduleIterable(input, scheduler);
}
}
+4 -16
View File
@@ -1,24 +1,12 @@
import { Observable } from '../Observable';
import { Subscription } from '../Subscription';
import { observable as Symbol_observable } from '../symbol/observable';
import { subscribeToObservable } from '../util/subscribeToObservable';
import { InteropObservable, SchedulerLike, Subscribable } from '../types';
import { InteropObservable, SchedulerLike } from '../types';
import { scheduleObservable } from '../scheduled/scheduleObservable';
export function fromObservable<T>(input: InteropObservable<T>, scheduler: SchedulerLike) {
export function fromObservable<T>(input: InteropObservable<T>, scheduler?: SchedulerLike) {
if (!scheduler) {
return new Observable<T>(subscribeToObservable(input));
} else {
return new Observable<T>(subscriber => {
const sub = new Subscription();
sub.add(scheduler.schedule(() => {
const observable: Subscribable<T> = input[Symbol_observable]();
sub.add(observable.subscribe({
next(value) { sub.add(scheduler.schedule(() => subscriber.next(value))); },
error(err) { sub.add(scheduler.schedule(() => subscriber.error(err))); },
complete() { sub.add(scheduler.schedule(() => subscriber.complete())); },
}));
}));
return sub;
});
return scheduleObservable(input, scheduler);
}
}
+2 -16
View File
@@ -1,26 +1,12 @@
import { Observable } from '../Observable';
import { SchedulerLike } from '../types';
import { Subscription } from '../Subscription';
import { subscribeToPromise } from '../util/subscribeToPromise';
import { schedulePromise } from '../scheduled/schedulePromise';
export function fromPromise<T>(input: PromiseLike<T>, scheduler?: SchedulerLike) {
if (!scheduler) {
return new Observable<T>(subscribeToPromise(input));
} else {
return new Observable<T>(subscriber => {
const sub = new Subscription();
sub.add(scheduler.schedule(() => input.then(
value => {
sub.add(scheduler.schedule(() => {
subscriber.next(value);
sub.add(scheduler.schedule(() => subscriber.complete()));
}));
},
err => {
sub.add(scheduler.schedule(() => subscriber.error(err)));
}
)));
return sub;
});
return schedulePromise(input, scheduler);
}
}
+2 -2
View File
@@ -57,7 +57,7 @@ export interface GenerateOptions<T, S> extends GenerateBaseOptions<S> {
* const res = generate(0, x => x < 10, x => x + 1, x => x);
*
* @example <caption>Using asap scheduler, produces sequence of 2, 3, 5, then completes.</caption>
* const res = generate(1, x => x < 5, x => * 2, x => x + 1, asap);
* const res = generate(1, x => x < 5, x => x * 2, x => x + 1, asap);
*
* @see {@link from}
* @see {@link Observable}
@@ -193,7 +193,7 @@ export interface GenerateOptions<T, S> extends GenerateBaseOptions<S> {
*
*
* @see {@link from}
* @see {@link create}
* @see {@link index/Observable.create}
*
* @param {S} initialState Initial state.
* @param {function (state: S): boolean} condition Condition to terminate generation (upon returning false).
+5 -3
View File
@@ -27,7 +27,9 @@ import { SubscribableOrPromise } from '../types';
*
* ## Examples
* ### Change at runtime which Observable will be subscribed
* ```javascript
* ```ts
* import { iif, of } from 'rxjs';
*
* let subscribeToFirst;
* const firstOrSecond = iif(
* () => subscribeToFirst,
@@ -50,7 +52,7 @@ import { SubscribableOrPromise } from '../types';
* ```
*
* ### Control an access to an Observable
* ```javascript
* ```ts
* let accessGranted;
* const observableIfYouHaveAccess = iif(
* () => accessGranted,
@@ -94,5 +96,5 @@ export function iif<T, F>(
trueResult: SubscribableOrPromise<T> = EMPTY,
falseResult: SubscribableOrPromise<F> = EMPTY
): Observable<T|F> {
return defer<T|F>(() => condition() ? trueResult : falseResult);
return defer(() => condition() ? trueResult : falseResult);
}
+1 -1
View File
@@ -22,7 +22,7 @@ import { Subscriber } from '../Subscriber';
*
* ## Example
* Emits ascending numbers, one every second (1000ms) up to the number 3
* ```javascript
* ```ts
* import { interval } from 'rxjs';
* import { take } from 'rxjs/operators';
*
+48 -14
View File
@@ -5,19 +5,48 @@ import { mergeAll } from '../operators/mergeAll';
import { fromArray } from './fromArray';
/* tslint:disable:max-line-length */
export function merge<T>(v1: ObservableInput<T>, scheduler?: SchedulerLike): Observable<T>;
export function merge<T>(v1: ObservableInput<T>, concurrent?: number, scheduler?: SchedulerLike): Observable<T>;
export function merge<T, T2>(v1: ObservableInput<T>, v2: ObservableInput<T2>, scheduler?: SchedulerLike): Observable<T | T2>;
export function merge<T, T2>(v1: ObservableInput<T>, v2: ObservableInput<T2>, concurrent?: number, scheduler?: SchedulerLike): Observable<T | T2>;
export function merge<T, T2, T3>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, scheduler?: SchedulerLike): Observable<T | T2 | T3>;
export function merge<T, T2, T3>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, concurrent?: number, scheduler?: SchedulerLike): Observable<T | T2 | T3>;
export function merge<T, T2, T3, T4>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, scheduler?: SchedulerLike): Observable<T | T2 | T3 | T4>;
export function merge<T, T2, T3, T4>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, concurrent?: number, scheduler?: SchedulerLike): Observable<T | T2 | T3 | T4>;
export function merge<T, T2, T3, T4, T5>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>, scheduler?: SchedulerLike): Observable<T | T2 | T3 | T4 | T5>;
export function merge<T, T2, T3, T4, T5>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>, concurrent?: number, scheduler?: SchedulerLike): Observable<T | T2 | T3 | T4 | T5>;
export function merge<T, T2, T3, T4, T5, T6>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>, v6: ObservableInput<T6>, scheduler?: SchedulerLike): Observable<T | T2 | T3 | T4 | T5 | T6>;
export function merge<T, T2, T3, T4, T5, T6>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>, v6: ObservableInput<T6>, concurrent?: number, scheduler?: SchedulerLike): Observable<T | T2 | T3 | T4 | T5 | T6>;
/** @deprecated use {@link scheduled} and {@link mergeAll} (e.g. `scheduled([ob1, ob2, ob3], scheduled).pipe(mergeAll())*/
export function merge<T>(v1: ObservableInput<T>, scheduler: SchedulerLike): Observable<T>;
/** @deprecated use {@link scheduled} and {@link mergeAll} (e.g. `scheduled([ob1, ob2, ob3], scheduled).pipe(mergeAll())*/
export function merge<T>(v1: ObservableInput<T>, concurrent: number, scheduler: SchedulerLike): Observable<T>;
/** @deprecated use {@link scheduled} and {@link mergeAll} (e.g. `scheduled([ob1, ob2, ob3], scheduled).pipe(mergeAll())*/
export function merge<T, T2>(v1: ObservableInput<T>, v2: ObservableInput<T2>, scheduler: SchedulerLike): Observable<T | T2>;
/** @deprecated use {@link scheduled} and {@link mergeAll} (e.g. `scheduled([ob1, ob2, ob3], scheduled).pipe(mergeAll())*/
export function merge<T, T2>(v1: ObservableInput<T>, v2: ObservableInput<T2>, concurrent: number, scheduler: SchedulerLike): Observable<T | T2>;
/** @deprecated use {@link scheduled} and {@link mergeAll} (e.g. `scheduled([ob1, ob2, ob3], scheduled).pipe(mergeAll())*/
export function merge<T, T2, T3>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, scheduler: SchedulerLike): Observable<T | T2 | T3>;
/** @deprecated use {@link scheduled} and {@link mergeAll} (e.g. `scheduled([ob1, ob2, ob3], scheduled).pipe(mergeAll())*/
export function merge<T, T2, T3>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, concurrent: number, scheduler: SchedulerLike): Observable<T | T2 | T3>;
/** @deprecated use {@link scheduled} and {@link mergeAll} (e.g. `scheduled([ob1, ob2, ob3], scheduled).pipe(mergeAll())*/
export function merge<T, T2, T3, T4>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, scheduler: SchedulerLike): Observable<T | T2 | T3 | T4>;
/** @deprecated use {@link scheduled} and {@link mergeAll} (e.g. `scheduled([ob1, ob2, ob3], scheduled).pipe(mergeAll())*/
export function merge<T, T2, T3, T4>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, concurrent: number, scheduler: SchedulerLike): Observable<T | T2 | T3 | T4>;
/** @deprecated use {@link scheduled} and {@link mergeAll} (e.g. `scheduled([ob1, ob2, ob3], scheduled).pipe(mergeAll())*/
export function merge<T, T2, T3, T4, T5>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>, scheduler: SchedulerLike): Observable<T | T2 | T3 | T4 | T5>;
/** @deprecated use {@link scheduled} and {@link mergeAll} (e.g. `scheduled([ob1, ob2, ob3], scheduled).pipe(mergeAll())*/
export function merge<T, T2, T3, T4, T5>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>, concurrent: number, scheduler: SchedulerLike): Observable<T | T2 | T3 | T4 | T5>;
/** @deprecated use {@link scheduled} and {@link mergeAll} (e.g. `scheduled([ob1, ob2, ob3], scheduled).pipe(mergeAll())*/
export function merge<T, T2, T3, T4, T5, T6>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>, v6: ObservableInput<T6>, scheduler: SchedulerLike): Observable<T | T2 | T3 | T4 | T5 | T6>;
/** @deprecated use {@link scheduled} and {@link mergeAll} (e.g. `scheduled([ob1, ob2, ob3], scheduled).pipe(mergeAll())*/
export function merge<T, T2, T3, T4, T5, T6>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>, v6: ObservableInput<T6>, concurrent: number, scheduler: SchedulerLike): Observable<T | T2 | T3 | T4 | T5 | T6>;
export function merge<T>(v1: ObservableInput<T>): Observable<T>;
export function merge<T>(v1: ObservableInput<T>, concurrent?: number): Observable<T>;
export function merge<T, T2>(v1: ObservableInput<T>, v2: ObservableInput<T2>): Observable<T | T2>;
export function merge<T, T2>(v1: ObservableInput<T>, v2: ObservableInput<T2>, concurrent?: number): Observable<T | T2>;
export function merge<T, T2, T3>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>): Observable<T | T2 | T3>;
export function merge<T, T2, T3>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, concurrent?: number): Observable<T | T2 | T3>;
export function merge<T, T2, T3, T4>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>): Observable<T | T2 | T3 | T4>;
export function merge<T, T2, T3, T4>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, concurrent?: number): Observable<T | T2 | T3 | T4>;
export function merge<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 merge<T, T2, T3, T4, T5>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>, concurrent?: number): Observable<T | T2 | T3 | T4 | T5>;
export function merge<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 merge<T, T2, T3, T4, T5, T6>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>, v6: ObservableInput<T6>, concurrent?: number): Observable<T | T2 | T3 | T4 | T5 | T6>;
export function merge<T>(...observables: (ObservableInput<T> | number)[]): Observable<T>;
/** @deprecated use {@link scheduled} and {@link mergeAll} (e.g. `scheduled([ob1, ob2, ob3], scheduled).pipe(mergeAll())*/
export function merge<T>(...observables: (ObservableInput<T> | SchedulerLike | number)[]): Observable<T>;
export function merge<T, R>(...observables: (ObservableInput<any> | number)[]): Observable<R>;
/** @deprecated use {@link scheduled} and {@link mergeAll} (e.g. `scheduled([ob1, ob2, ob3], scheduled).pipe(mergeAll())*/
export function merge<T, R>(...observables: (ObservableInput<any> | SchedulerLike | number)[]): Observable<R>;
/* tslint:enable:max-line-length */
/**
@@ -37,7 +66,9 @@ export function merge<T, R>(...observables: (ObservableInput<any> | SchedulerLik
*
* ## Examples
* ### Merge together two Observables: 1s interval and clicks
* ```javascript
* ```ts
* import { merge, fromEvent, interval } from 'rxjs';
*
* const clicks = fromEvent(document, 'click');
* const timer = interval(1000);
* const clicksOrTimer = merge(clicks, timer);
@@ -51,7 +82,10 @@ export function merge<T, R>(...observables: (ObservableInput<any> | SchedulerLik
* ```
*
* ### Merge together 3 Observables, but only 2 run concurrently
* ```javascript
* ```ts
* import { merge, interval } from 'rxjs';
* import { take } from 'rxjs/operators';
*
* const timer1 = interval(1000).pipe(take(10));
* const timer2 = interval(2000).pipe(take(6));
* const timer3 = interval(500).pipe(take(10));
+4 -1
View File
@@ -14,7 +14,10 @@ import { noop } from '../util/noop';
*
* ## Example
* ### Emit the number 7, then never emit anything else (not even complete)
* ```javascript
* ```ts
* import { NEVER } from 'rxjs';
* import { startWith } from 'rxjs/operators';
*
* function info() {
* console.log('Will not be called');
* }
+43 -23
View File
@@ -1,24 +1,47 @@
import { SchedulerLike } from '../types';
import { isScheduler } from '../util/isScheduler';
import { fromArray } from './fromArray';
import { empty } from './empty';
import { scalar } from './scalar';
import { Observable } from '../Observable';
import { scheduleArray } from '../scheduled/scheduleArray';
/* tslint:disable:max-line-length */
export function of<T>(a: T, scheduler?: SchedulerLike): Observable<T>;
export function of<T, T2>(a: T, b: T2, scheduler?: SchedulerLike): Observable<T | T2>;
export function of<T, T2, T3>(a: T, b: T2, c: T3, scheduler?: SchedulerLike): Observable<T | T2 | T3>;
export function of<T, T2, T3, T4>(a: T, b: T2, c: T3, d: T4, scheduler?: SchedulerLike): Observable<T | T2 | T3 | T4>;
export function of<T, T2, T3, T4, T5>(a: T, b: T2, c: T3, d: T4, e: T5, scheduler?: SchedulerLike): Observable<T | T2 | T3 | T4 | T5>;
export function of<T, T2, T3, T4, T5, T6>(a: T, b: T2, c: T3, d: T4, e: T5, f: T6, scheduler?: SchedulerLike): Observable<T | T2 | T3 | T4 | T5 | T6>;
export function of<T, T2, T3, T4, T5, T6, T7>(a: T, b: T2, c: T3, d: T4, e: T5, f: T6, g: T7, scheduler?: SchedulerLike):
/** @deprecated use {@link scheduled} instead `scheduled([a, b, c], scheduler)` */
export function of<T>(a: T, scheduler: SchedulerLike): Observable<T>;
/** @deprecated use {@link scheduled} instead `scheduled([a, b, c], scheduler)` */
export function of<T, T2>(a: T, b: T2, scheduler: SchedulerLike): Observable<T | T2>;
/** @deprecated use {@link scheduled} instead `scheduled([a, b, c], scheduler)` */
export function of<T, T2, T3>(a: T, b: T2, c: T3, scheduler: SchedulerLike): Observable<T | T2 | T3>;
/** @deprecated use {@link scheduled} instead `scheduled([a, b, c], scheduler)` */
export function of<T, T2, T3, T4>(a: T, b: T2, c: T3, d: T4, scheduler: SchedulerLike): Observable<T | T2 | T3 | T4>;
/** @deprecated use {@link scheduled} instead `scheduled([a, b, c], scheduler)` */
export function of<T, T2, T3, T4, T5>(a: T, b: T2, c: T3, d: T4, e: T5, scheduler: SchedulerLike): Observable<T | T2 | T3 | T4 | T5>;
/** @deprecated use {@link scheduled} instead `scheduled([a, b, c], scheduler)` */
export function of<T, T2, T3, T4, T5, T6>(a: T, b: T2, c: T3, d: T4, e: T5, f: T6, scheduler: SchedulerLike): Observable<T | T2 | T3 | T4 | T5 | T6>;
/** @deprecated use {@link scheduled} instead `scheduled([a, b, c], scheduler)` */
export function of<T, T2, T3, T4, T5, T6, T7>(a: T, b: T2, c: T3, d: T4, e: T5, f: T6, g: T7, scheduler: SchedulerLike):
Observable<T | T2 | T3 | T4 | T5 | T6 | T7>;
export function of<T, T2, T3, T4, T5, T6, T7, T8>(a: T, b: T2, c: T3, d: T4, e: T5, f: T6, g: T7, h: T8, scheduler?: SchedulerLike):
/** @deprecated use {@link scheduled} instead `scheduled([a, b, c], scheduler)` */
export function of<T, T2, T3, T4, T5, T6, T7, T8>(a: T, b: T2, c: T3, d: T4, e: T5, f: T6, g: T7, h: T8, scheduler: SchedulerLike):
Observable<T | T2 | T3 | T4 | T5 | T6 | T7 | T8>;
export function of<T, T2, T3, T4, T5, T6, T7, T8, T9>(a: T, b: T2, c: T3, d: T4, e: T5, f: T6, g: T7, h: T8, i: T9, scheduler?: SchedulerLike):
/** @deprecated use {@link scheduled} instead `scheduled([a, b, c], scheduler)` */
export function of<T, T2, T3, T4, T5, T6, T7, T8, T9>(a: T, b: T2, c: T3, d: T4, e: T5, f: T6, g: T7, h: T8, i: T9, scheduler: SchedulerLike):
Observable<T | T2 | T3 | T4 | T5 | T6 | T7 | T8 | T9>;
export function of<T>(...args: Array<T | SchedulerLike>): Observable<T>;
export function of<T>(...args: (T | SchedulerLike)[]): Observable<T>;
// TODO(benlesh): Update the typings for this when we can switch to TS 3.x
export function of<T>(a: T): Observable<T>;
export function of<T, T2>(a: T, b: T2): Observable<T | T2>;
export function of<T, T2, T3>(a: T, b: T2, c: T3): Observable<T | T2 | T3>;
export function of<T, T2, T3, T4>(a: T, b: T2, c: T3, d: T4): Observable<T | T2 | T3 | T4>;
export function of<T, T2, T3, T4, T5>(a: T, b: T2, c: T3, d: T4, e: T5): Observable<T | T2 | T3 | T4 | T5>;
export function of<T, T2, T3, T4, T5, T6>(a: T, b: T2, c: T3, d: T4, e: T5, f: T6): Observable<T | T2 | T3 | T4 | T5 | T6>;
export function of<T, T2, T3, T4, T5, T6, T7>(a: T, b: T2, c: T3, d: T4, e: T5, f: T6, g: T7):
Observable<T | T2 | T3 | T4 | T5 | T6 | T7>;
export function of<T, T2, T3, T4, T5, T6, T7, T8>(a: T, b: T2, c: T3, d: T4, e: T5, f: T6, g: T7, h: T8):
Observable<T | T2 | T3 | T4 | T5 | T6 | T7 | T8>;
export function of<T, T2, T3, T4, T5, T6, T7, T8, T9>(a: T, b: T2, c: T3, d: T4, e: T5, f: T6, g: T7, h: T8, i: T9):
Observable<T | T2 | T3 | T4 | T5 | T6 | T7 | T8 | T9>;
export function of<T>(...args: T[]): Observable<T>;
/* tslint:enable:max-line-length */
/**
@@ -35,7 +58,9 @@ export function of<T>(...args: Array<T | SchedulerLike>): Observable<T>;
*
* Emit the values `10, 20, 30`
*
* ```javascript
* ```ts
* import { of } from 'rxjs';
*
* of(10, 20, 30)
* .subscribe(
* next => console.log('next:', next),
@@ -51,7 +76,9 @@ export function of<T>(...args: Array<T | SchedulerLike>): Observable<T>;
*
* Emit the array `[1,2,3]`
*
* ```javascript
* ```ts
* import { of } from 'rxjs';
*
* of([1,2,3])
* .subscribe(
* next => console.log('next:', next),
@@ -76,15 +103,8 @@ export function of<T>(...args: Array<T | SchedulerLike>): Observable<T> {
let scheduler = args[args.length - 1] as SchedulerLike;
if (isScheduler(scheduler)) {
args.pop();
return scheduleArray(args as T[], scheduler);
} else {
scheduler = undefined;
}
switch (args.length) {
case 0:
return empty(scheduler);
case 1:
return scheduler ? fromArray(args as T[], scheduler) : scalar(args[0] as T);
default:
return fromArray(args as T[], scheduler);
return fromArray(args as T[]);
}
}
+1 -1
View File
@@ -38,7 +38,7 @@ export function onErrorResumeNext<R>(array: ObservableInput<any>[]): Observable<
*
* ## Example
* Subscribe to the next Observable after map fails</caption>
* ```javascript
* ```ts
* import { onErrorResumeNext, of } from 'rxjs';
* import { map } from 'rxjs/operators';
*
+6 -4
View File
@@ -21,7 +21,9 @@ import { Subscription } from '../Subscription';
* pass a {@link SchedulerLike} as a second argument to `pairs`.
*
* @example <caption>Converts a javascript object to an Observable</caption>
* ```javascript
* ```ts
* import { pairs } from 'rxjs';
*
* const obj = {
* foo: 42,
* bar: 56,
@@ -36,9 +38,9 @@ import { Subscription } from '../Subscription';
* );
*
* // Logs:
* // ["foo": 42],
* // ["bar": 56],
* // ["baz": 78],
* // ["foo", 42],
* // ["bar", 56],
* // ["baz", 78],
* // "the end!"
* ```
*
+67
View File
@@ -0,0 +1,67 @@
import { not } from '../util/not';
import { subscribeTo } from '../util/subscribeTo';
import { filter } from '../operators/filter';
import { ObservableInput } from '../types';
import { Observable } from '../Observable';
/**
* Splits the source Observable into two, one with values that satisfy a
* predicate, and another with values that don't satisfy the predicate.
*
* <span class="informal">It's like {@link filter}, but returns two Observables:
* one like the output of {@link filter}, and the other with values that did not
* pass the condition.</span>
*
* ![](partition.png)
*
* `partition` outputs an array with two Observables that partition the values
* from the source Observable through the given `predicate` function. The first
* Observable in that array emits source values for which the predicate argument
* returns true. The second Observable emits source values for which the
* predicate returns false. The first behaves like {@link filter} and the second
* behaves like {@link filter} with the predicate negated.
*
* ## Example
* Partition a set of numbers into odds and evens observables
* ```ts
* import { of, partition } from 'rxjs';
*
* const observableValues = of(1, 2, 3, 4, 5, 6);
* const [evens$, odds$] = partition(observableValues, (value, index) => value % 2 === 0);
*
* odds$.subscribe(x => console.log('odds', x));
* evens$.subscribe(x => console.log('evens', x));
*
* // Logs:
* // odds 1
* // odds 3
* // odds 5
* // evens 2
* // evens 4
* // evens 6
* ```
*
* @see {@link filter}
*
* @param {function(value: T, index: number): boolean} predicate A function that
* evaluates each value emitted by the source Observable. If it returns `true`,
* the value is emitted on the first Observable in the returned array, if
* `false` the value is emitted on the second Observable in the array. The
* `index` parameter is the number `i` for the i-th source emission that has
* happened since the subscription, starting from the number `0`.
* @param {any} [thisArg] An optional argument to determine the value of `this`
* in the `predicate` function.
* @return {[Observable<T>, Observable<T>]} An array with two Observables: one
* with values that passed the predicate, and another with values that did not
* pass the predicate.
*/
export function partition<T>(
source: ObservableInput<T>,
predicate: (value: T, index: number) => boolean,
thisArg?: any
): [Observable<T>, Observable<T>] {
return [
filter(predicate, thisArg)(new Observable<T>(subscribeTo(source))),
filter(not(predicate, thisArg) as any)(new Observable<T>(subscribeTo(source)))
] as [Observable<T>, Observable<T>];
}
+29 -8
View File
@@ -4,18 +4,42 @@ import { fromArray } from './fromArray';
import { Operator } from '../Operator';
import { Subscriber } from '../Subscriber';
import { Subscription } from '../Subscription';
import { TeardownLogic } from '../types';
import { TeardownLogic, ObservableInput } from '../types';
import { OuterSubscriber } from '../OuterSubscriber';
import { InnerSubscriber } from '../InnerSubscriber';
import { subscribeToResult } from '../util/subscribeToResult';
// tslint:disable:max-line-length
export function race<A>(arg: [ObservableInput<A>]): Observable<A>;
export function race<A, B>(arg: [ObservableInput<A>, ObservableInput<B>]): Observable<A | B>;
export function race<A, B, C>(arg: [ObservableInput<A>, ObservableInput<B>, ObservableInput<C>]): Observable<A | B | C>;
export function race<A, B, C, D>(arg: [ObservableInput<A>, ObservableInput<B>, ObservableInput<C>, ObservableInput<D>]): Observable<A | B | C | D>;
export function race<A, B, C, D, E>(arg: [ObservableInput<A>, ObservableInput<B>, ObservableInput<C>, ObservableInput<D>, ObservableInput<E>]): Observable<A | B | C | D | E>;
export function race<T>(arg: ObservableInput<T>[]): Observable<T>;
export function race(arg: ObservableInput<any>[]): Observable<{}>;
export function race<A>(a: ObservableInput<A>): Observable<A>;
export function race<A, B>(a: ObservableInput<A>, b: ObservableInput<B>): Observable<A | B>;
export function race<A, B, C>(a: ObservableInput<A>, b: ObservableInput<B>, c: ObservableInput<C>): Observable<A | B | C>;
export function race<A, B, C, D>(a: ObservableInput<A>, b: ObservableInput<B>, c: ObservableInput<C>, d: ObservableInput<D>): Observable<A | B | C | D>;
export function race<A, B, C, D, E>(a: ObservableInput<A>, b: ObservableInput<B>, c: ObservableInput<C>, d: ObservableInput<D>, e: ObservableInput<E>): Observable<A | B | C | D | E>;
// tslint:enable:max-line-length
export function race<T>(observables: ObservableInput<T>[]): Observable<T>;
export function race(observables: ObservableInput<any>[]): Observable<{}>;
export function race<T>(...observables: ObservableInput<T>[]): Observable<T>;
export function race(...observables: ObservableInput<any>[]): Observable<{}>;
/**
* Returns an Observable that mirrors the first source Observable to emit an item.
*
* ## Example
* ### Subscribes to the observable that was the first to start emitting.
*
* ```javascript
* ```ts
* import { race, interval } from 'rxjs';
* import { mapTo } from 'rxjs/operators';
*
* const obs1 = interval(1000).pipe(mapTo('fast one'));
* const obs2 = interval(3000).pipe(mapTo('medium one'));
* const obs3 = interval(5000).pipe(mapTo('slow one'));
@@ -35,17 +59,14 @@ import { subscribeToResult } from '../util/subscribeToResult';
* @name race
* @owner Observable
*/
export function race<T>(observables: Array<Observable<T>>): Observable<T>;
export function race<T>(observables: Array<Observable<any>>): Observable<T>;
export function race<T>(...observables: Array<Observable<T> | Array<Observable<T>>>): Observable<T>;
export function race<T>(...observables: Array<Observable<any> | Array<Observable<any>>>): Observable<T> {
export function race<T>(...observables: ObservableInput<any>[]): Observable<T> {
// if the only argument is an array, it was most likely called with
// `race([obs1, obs2, ...])`
if (observables.length === 1) {
if (isArray(observables[0])) {
observables = <Array<Observable<any>>>observables[0];
observables = observables[0] as Observable<any>[];
} else {
return <Observable<any>>observables[0];
return observables[0] as Observable<T>;
}
}
+10 -3
View File
@@ -16,7 +16,9 @@ import { Observable } from '../Observable';
*
* ## Example
* Emits the numbers 1 to 10</caption>
* ```javascript
* ```ts
* import { range } from 'rxjs';
*
* const numbers = range(1, 10);
* numbers.subscribe(x => console.log(x));
* ```
@@ -24,7 +26,7 @@ import { Observable } from '../Observable';
* @see {@link index/interval}
*
* @param {number} [start=0] The value of the first integer in the sequence.
* @param {number} [count=0] The number of sequential integers to generate.
* @param {number} count The number of sequential integers to generate.
* @param {SchedulerLike} [scheduler] A {@link SchedulerLike} to use for scheduling
* the emissions of the notifications.
* @return {Observable} An Observable of numbers that emits a finite range of
@@ -34,9 +36,14 @@ import { Observable } from '../Observable';
* @owner Observable
*/
export function range(start: number = 0,
count: number = 0,
count?: number,
scheduler?: SchedulerLike): Observable<number> {
return new Observable<number>(subscriber => {
if (count === undefined) {
count = start;
start = 0;
}
let index = 0;
let current = start;
-11
View File
@@ -1,11 +0,0 @@
import { Observable } from '../Observable';
export function scalar<T>(value: T) {
const result = new Observable<T>(subscriber => {
subscriber.next(value);
subscriber.complete();
});
result._isScalar = true;
(result as any).value = value;
return result;
}
+3 -3
View File
@@ -17,7 +17,7 @@ import { Subscriber } from '../Subscriber';
*
* ## Examples
* ### Emit the number 7, then emit an error
* ```javascript
* ```ts
* import { throwError, concat, of } from 'rxjs';
*
* const result = concat(of(7), throwError(new Error('oops!')));
@@ -30,8 +30,8 @@ import { Subscriber } from '../Subscriber';
*
* ---
*
* ### Map and flatten numbers to the sequence 'a', 'b', 'c', but throw an error for 13
* ```javascript
* ### Map and flatten numbers to the sequence 'a', 'b', 'c', but throw an error for 2
* ```ts
* import { throwError, interval, of } from 'rxjs';
* import { mergeMap } from 'rxjs/operators';
*
+6 -2
View File
@@ -25,13 +25,17 @@ import { Subscriber } from '../Subscriber';
*
* ## Examples
* ### Emits ascending numbers, one every second (1000ms), starting after 3 seconds
* ```javascript
* ```ts
* import { timer } from 'rxjs';
*
* const numbers = timer(3000, 1000);
* numbers.subscribe(x => console.log(x));
* ```
*
* ### Emits one number after five seconds
* ```javascript
* ```ts
* import { timer } from 'rxjs';
*
* const numbers = timer(5000);
* numbers.subscribe(x => console.log(x));
* ```
+26 -21
View File
@@ -2,7 +2,7 @@ import { Observable } from '../Observable';
import { fromArray } from './fromArray';
import { isArray } from '../util/isArray';
import { Operator } from '../Operator';
import { ObservableInput, PartialObserver } from '../types';
import { ObservableInput, PartialObserver, ObservedValueOf } from '../types';
import { Subscriber } from '../Subscriber';
import { Subscription } from '../Subscription';
import { OuterSubscriber } from '../OuterSubscriber';
@@ -12,33 +12,33 @@ import { iterator as Symbol_iterator } from '../../internal/symbol/iterator';
/* tslint:disable:max-line-length */
/** @deprecated resultSelector is no longer supported, pipe to map instead */
export function zip<T, R>(v1: ObservableInput<T>, resultSelector: (v1: T) => R): Observable<R>;
export function zip<O1 extends ObservableInput<any>, R>(v1: O1, resultSelector: (v1: ObservedValueOf<O1>) => R): Observable<R>;
/** @deprecated resultSelector is no longer supported, pipe to map instead */
export function zip<T, T2, R>(v1: ObservableInput<T>, v2: ObservableInput<T2>, resultSelector: (v1: T, v2: T2) => R): Observable<R>;
export function zip<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, R>(v1: O1, v2: O2, resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>) => R): Observable<R>;
/** @deprecated resultSelector is no longer supported, pipe to map instead */
export function zip<T, T2, T3, R>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, resultSelector: (v1: T, v2: T2, v3: T3) => R): Observable<R>;
export function zip<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, R>(v1: O1, v2: O2, v3: O3, resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>) => R): Observable<R>;
/** @deprecated resultSelector is no longer supported, pipe to map instead */
export function zip<T, T2, T3, T4, R>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, resultSelector: (v1: T, v2: T2, v3: T3, v4: T4) => R): Observable<R>;
export function zip<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, R>(v1: O1, v2: O2, v3: O3, v4: O4, resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>) => R): Observable<R>;
/** @deprecated resultSelector is no longer supported, pipe to map instead */
export function zip<T, T2, T3, T4, T5, R>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>, resultSelector: (v1: T, v2: T2, v3: T3, v4: T4, v5: T5) => R): Observable<R>;
export function zip<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, O5 extends ObservableInput<any>, R>(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>, v5: ObservedValueOf<O5>) => R): Observable<R>;
/** @deprecated resultSelector is no longer supported, pipe to map instead */
export function zip<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>, resultSelector: (v1: T, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6) => R): Observable<R>;
export function zip<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, O5 extends ObservableInput<any>, O6 extends ObservableInput<any>, R>(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, v6: O6, resultSelector: (v1: ObservedValueOf<O1>, v2: ObservedValueOf<O2>, v3: ObservedValueOf<O3>, v4: ObservedValueOf<O4>, v5: ObservedValueOf<O5>, v6: ObservedValueOf<O6>) => R): Observable<R>;
export function zip<T, T2>(v1: ObservableInput<T>, v2: ObservableInput<T2>): Observable<[T, T2]>;
export function zip<T, T2, T3>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>): Observable<[T, T2, T3]>;
export function zip<T, T2, T3, T4>(v1: ObservableInput<T>, v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>): Observable<[T, T2, T3, T4]>;
export function zip<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 zip<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 zip<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>>(v1: O1, v2: O2): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>]>;
export function zip<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>>(v1: O1, v2: O2, v3: O3): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>]>;
export function zip<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>>(v1: O1, v2: O2, v3: O3, v4: O4): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>]>;
export function zip<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, O5 extends ObservableInput<any>>(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>]>;
export function zip<O1 extends ObservableInput<any>, O2 extends ObservableInput<any>, O3 extends ObservableInput<any>, O4 extends ObservableInput<any>, O5 extends ObservableInput<any>, O6 extends ObservableInput<any>>(v1: O1, v2: O2, v3: O3, v4: O4, v5: O5, v6: O6): Observable<[ObservedValueOf<O1>, ObservedValueOf<O2>, ObservedValueOf<O3>, ObservedValueOf<O4>, ObservedValueOf<O5>, ObservedValueOf<O6>]>;
export function zip<T>(array: ObservableInput<T>[]): Observable<T[]>;
export function zip<O extends ObservableInput<any>>(array: O[]): Observable<ObservedValueOf<O>[]>;
export function zip<R>(array: ObservableInput<any>[]): Observable<R>;
/** @deprecated resultSelector is no longer supported, pipe to map instead */
export function zip<T, R>(array: ObservableInput<T>[], resultSelector: (...values: Array<T>) => R): Observable<R>;
export function zip<O extends ObservableInput<any>, R>(array: O[], resultSelector: (...values: ObservedValueOf<O>[]) => R): Observable<R>;
/** @deprecated resultSelector is no longer supported, pipe to map instead */
export function zip<R>(array: ObservableInput<any>[], resultSelector: (...values: Array<any>) => R): Observable<R>;
export function zip<R>(array: ObservableInput<any>[], resultSelector: (...values: any[]) => R): Observable<R>;
export function zip<T>(...observables: Array<ObservableInput<T>>): Observable<T[]>;
export function zip<T, R>(...observables: Array<ObservableInput<T> | ((...values: Array<T>) => R)>): Observable<R>;
export function zip<O extends ObservableInput<any>>(...observables: O[]): Observable<ObservedValueOf<O>[]>;
export function zip<O extends ObservableInput<any>, R>(...observables: Array<O | ((...values: ObservedValueOf<O>[]) => R)>): Observable<R>;
export function zip<R>(...observables: Array<ObservableInput<any> | ((...values: Array<any>) => R)>): Observable<R>;
/* tslint:enable:max-line-length */
@@ -46,18 +46,21 @@ export function zip<R>(...observables: Array<ObservableInput<any> | ((...values:
* Combines multiple Observables to create an Observable whose values are calculated from the values, in order, of each
* of its input Observables.
*
* If the latest parameter is a function, this function is used to compute the created value from the input values.
* If the last parameter is a function, this function is used to compute the created value from the input values.
* Otherwise, an array of the input values is returned.
*
* ## Example
* Combine age and name from different sources
* ```javascript
* ```ts
* import { zip, of } from 'rxjs';
* import { map } from 'rxjs/operators';
*
* let age$ = of<number>(27, 25, 29);
* let name$ = of<string>('Foo', 'Bar', 'Beer');
* let isDev$ = of<boolean>(true, true, false);
*
* zip(age$, name$, isDev$).pipe(
* map((age: number, name: string, isDev: boolean) => ({ age, name, isDev })),
* map(([age, name, isDev]) => ({ age, name, isDev })),
* )
* .subscribe(x => console.log(x));
*
@@ -72,7 +75,9 @@ export function zip<R>(...observables: Array<ObservableInput<any> | ((...values:
* @name zip
* @owner Observable
*/
export function zip<T, R>(...observables: Array<ObservableInput<any> | ((...values: Array<any>) => R)>): Observable<R> {
export function zip<O extends ObservableInput<any>, R>(
...observables: Array<O | ((...values: ObservedValueOf<O>[]) => R)>
): Observable<ObservedValueOf<O>[]|R> {
const resultSelector = <((...ys: Array<any>) => R)> observables[observables.length - 1];
if (typeof resultSelector === 'function') {
observables.pop();
+15 -12
View File
@@ -4,8 +4,6 @@ import { Observable } from '../Observable';
import { Subscription } from '../Subscription';
import { MonoTypeOperatorFunction, SubscribableOrPromise, TeardownLogic } from '../types';
import { tryCatch } from '../util/tryCatch';
import { errorObject } from '../util/errorObject';
import { OuterSubscriber } from '../OuterSubscriber';
import { subscribeToResult } from '../util/subscribeToResult';
@@ -33,7 +31,10 @@ import { subscribeToResult } from '../util/subscribeToResult';
* ## Example
*
* Emit clicks at a rate of at most one click per second
* ```javascript
* ```ts
* import { fromEvent, interval } from 'rxjs';
* import { audit } from 'rxjs/operators'
*
* const clicks = fromEvent(document, 'click');
* const result = clicks.pipe(audit(ev => interval(1000)));
* result.subscribe(x => console.log(x));
@@ -87,16 +88,18 @@ class AuditSubscriber<T, R> extends OuterSubscriber<T, R> {
this.value = value;
this.hasValue = true;
if (!this.throttled) {
const duration = tryCatch(this.durationSelector)(value);
if (duration === errorObject) {
this.destination.error(errorObject.e);
let duration;
try {
const { durationSelector } = this;
duration = durationSelector(value);
} catch (err) {
return this.destination.error(err);
}
const innerSubscription = subscribeToResult(this, duration);
if (!innerSubscription || innerSubscription.closed) {
this.clearThrottle();
} else {
const innerSubscription = subscribeToResult(this, duration);
if (!innerSubscription || innerSubscription.closed) {
this.clearThrottle();
} else {
this.add(this.throttled = innerSubscription);
}
this.add(this.throttled = innerSubscription);
}
}
}
+5 -2
View File
@@ -7,7 +7,7 @@ import { MonoTypeOperatorFunction, SchedulerLike } from '../types';
* Ignores source values for `duration` milliseconds, then emits the most recent
* value from the source Observable, then repeats this process.
*
* <span class="informal">When it sees a source values, it ignores that plus
* <span class="informal">When it sees a source value, it ignores that plus
* the next ones for `duration` milliseconds, and then it emits the most recent
* value from the source.</span>
*
@@ -27,7 +27,10 @@ import { MonoTypeOperatorFunction, SchedulerLike } from '../types';
* ## Example
*
* Emit clicks at a rate of at most one click per second
* ```javascript
* ```ts
* import { fromEvent } from 'rxjs';
* import { auditTime } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const result = clicks.pipe(auditTime(1000));
* result.subscribe(x => console.log(x));
+7 -4
View File
@@ -12,7 +12,7 @@ import { OperatorFunction } from '../types';
* <span class="informal">Collects values from the past as an array, and emits
* that array only when another Observable emits.</span>
*
* ![](buffer.png)
* ![](content/img/buffer.png)
*
* Buffers the incoming Observable values until the given `closingNotifier`
* Observable emits a value, at which point it emits the buffer on the output
@@ -23,10 +23,13 @@ import { OperatorFunction } from '../types';
*
* On every click, emit array of most recent interval events
*
* ```javascript
* ```ts
* import { fromEvent, interval } from 'rxjs';
* import { buffer } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const interval = interval(1000);
* const buffered = interval.pipe(buffer(clicks));
* const intervalEvents = interval(1000);
* const buffered = intervalEvents.pipe(buffer(clicks));
* buffered.subscribe(x => console.log(x));
* ```
*
+8 -2
View File
@@ -22,7 +22,10 @@ import { OperatorFunction, TeardownLogic } from '../types';
*
* Emit the last two click events as an array
*
* ```javascript
* ```ts
* import { fromEvent } from 'rxjs';
* import { bufferCount } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const buffered = clicks.pipe(bufferCount(2));
* buffered.subscribe(x => console.log(x));
@@ -30,7 +33,10 @@ import { OperatorFunction, TeardownLogic } from '../types';
*
* On every click, emit the last two click events as an array
*
* ```javascript
* ```ts
* import { fromEvent } from 'rxjs';
* import { bufferCount } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const buffered = clicks.pipe(bufferCount(2, 1));
* buffered.subscribe(x => console.log(x));
+8 -2
View File
@@ -33,7 +33,10 @@ export function bufferTime<T>(bufferTimeSpan: number, bufferCreationInterval: nu
*
* Every second, emit an array of the recent click events
*
* ```javascript
* ```ts
* import { fromEvent } from 'rxjs';
* import { bufferTime } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const buffered = clicks.pipe(bufferTime(1000));
* buffered.subscribe(x => console.log(x));
@@ -41,7 +44,10 @@ export function bufferTime<T>(bufferTimeSpan: number, bufferCreationInterval: nu
*
* Every 5 seconds, emit the click events from the next 2 seconds
*
* ```javascript
* ```ts
* import { fromEvent } from 'rxjs';
* import { bufferTime } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const buffered = clicks.pipe(bufferTime(2000, 5000));
* buffered.subscribe(x => console.log(x));
+5 -2
View File
@@ -25,11 +25,14 @@ import { OperatorFunction, SubscribableOrPromise } from '../types';
*
* Every other second, emit the click events from the next 500ms
*
* ```javascript
* ```ts
* import { fromEvent, interval, EMPTY } from 'rxjs';
* import { bufferToggle } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const openings = interval(1000);
* const buffered = clicks.pipe(bufferToggle(openings, i =>
* i % 2 ? interval(500) : empty()
* i % 2 ? interval(500) : EMPTY
* ));
* buffered.subscribe(x => console.log(x));
* ```
+16 -15
View File
@@ -2,8 +2,6 @@ import { Operator } from '../Operator';
import { Subscriber } from '../Subscriber';
import { Observable } from '../Observable';
import { Subscription } from '../Subscription';
import { tryCatch } from '../util/tryCatch';
import { errorObject } from '../util/errorObject';
import { OuterSubscriber } from '../OuterSubscriber';
import { InnerSubscriber } from '../InnerSubscriber';
import { subscribeToResult } from '../util/subscribeToResult';
@@ -27,7 +25,10 @@ import { OperatorFunction } from '../types';
*
* Emit an array of the last clicks every [1-5] random seconds
*
* ```javascript
* ```ts
* import { fromEvent, interval } from 'rxjs';
* import { bufferWhen } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const buffered = clicks.pipe(bufferWhen(() =>
* interval(1000 + Math.random() * 4000)
@@ -112,7 +113,6 @@ class BufferWhenSubscriber<T> extends OuterSubscriber<T, any> {
}
openBuffer() {
let { closingSubscription } = this;
if (closingSubscription) {
@@ -127,17 +127,18 @@ class BufferWhenSubscriber<T> extends OuterSubscriber<T, any> {
this.buffer = [];
const closingNotifier = tryCatch(this.closingSelector)();
if (closingNotifier === errorObject) {
this.error(errorObject.e);
} else {
closingSubscription = new Subscription();
this.closingSubscription = closingSubscription;
this.add(closingSubscription);
this.subscribing = true;
closingSubscription.add(subscribeToResult(this, closingNotifier));
this.subscribing = false;
let closingNotifier;
try {
const { closingSelector } = this;
closingNotifier = closingSelector();
} catch (err) {
return this.error(err);
}
closingSubscription = new Subscription();
this.closingSubscription = closingSubscription;
this.add(closingSubscription);
this.subscribing = true;
closingSubscription.add(subscribeToResult(this, closingNotifier));
this.subscribing = false;
}
}
+28 -15
View File
@@ -1,11 +1,15 @@
import {Operator} from '../Operator';
import {Subscriber} from '../Subscriber';
import {Observable} from '../Observable';
import { Operator } from '../Operator';
import { Subscriber } from '../Subscriber';
import { Observable } from '../Observable';
import {OuterSubscriber} from '../OuterSubscriber';
import { OuterSubscriber } from '../OuterSubscriber';
import { InnerSubscriber } from '../InnerSubscriber';
import {subscribeToResult} from '../util/subscribeToResult';
import {ObservableInput, OperatorFunction, MonoTypeOperatorFunction} from '../types';
import { subscribeToResult } from '../util/subscribeToResult';
import { ObservableInput, OperatorFunction, ObservedValueOf } from '../types';
/* tslint:disable:max-line-length */
export function catchError<T, O extends ObservableInput<any>>(selector: (err: any, caught: Observable<T>) => O): OperatorFunction<T, T | ObservedValueOf<O>>;
/* tslint:enable:max-line-length */
/**
* Catches errors on the observable to be handled by returning a new observable or throwing an error.
@@ -15,10 +19,13 @@ import {ObservableInput, OperatorFunction, MonoTypeOperatorFunction} from '../ty
* ## Examples
* Continues with a different Observable when there's an error
*
* ```javascript
* ```ts
* import { of } from 'rxjs';
* import { map, catchError } from 'rxjs/operators';
*
* of(1, 2, 3, 4, 5).pipe(
* map(n => {
* if (n == 4) {
* if (n === 4) {
* throw 'four!';
* }
* return n;
@@ -31,7 +38,10 @@ import {ObservableInput, OperatorFunction, MonoTypeOperatorFunction} from '../ty
*
* Retries the caught source Observable again in case of error, similar to retry() operator
*
* ```javascript
* ```ts
* import { of } from 'rxjs';
* import { map, catchError, take } from 'rxjs/operators';
*
* of(1, 2, 3, 4, 5).pipe(
* map(n => {
* if (n === 4) {
@@ -48,10 +58,13 @@ import {ObservableInput, OperatorFunction, MonoTypeOperatorFunction} from '../ty
*
* Throws a new error when the source Observable throws an error
*
* ```javascript
* ```ts
* import { of } from 'rxjs';
* import { map, catchError } from 'rxjs/operators';
*
* of(1, 2, 3, 4, 5).pipe(
* map(n => {
* if (n == 4) {
* if (n === 4) {
* throw 'four!';
* }
* return n;
@@ -74,10 +87,10 @@ import {ObservableInput, OperatorFunction, MonoTypeOperatorFunction} from '../ty
* catch `selector` function.
* @name catchError
*/
export function catchError<T>(selector: (err: any, caught: Observable<T>) => never): MonoTypeOperatorFunction<T>;
export function catchError<T, R>(selector: (err: any, caught: Observable<T>) => ObservableInput<R>): OperatorFunction<T, T | R>;
export function catchError<T, R>(selector: (err: any, caught: Observable<T>) => ObservableInput<R>): OperatorFunction<T, T | R> {
return function catchErrorOperatorFunction(source: Observable<T>): Observable<T | R> {
export function catchError<T, O extends ObservableInput<any>>(
selector: (err: any, caught: Observable<T>) => O
): OperatorFunction<T, T | ObservedValueOf<O>> {
return function catchErrorOperatorFunction(source: Observable<T>): Observable<T | ObservedValueOf<O>> {
const operator = new CatchOperator(selector);
const caught = source.lift(operator);
return (operator.caught = caught as Observable<T>);
+4 -2
View File
@@ -23,10 +23,12 @@ export function combineAll<R>(project: (...values: Array<any>) => R): OperatorFu
* ---
*
* ## Examples
*
* ### Map two click events to a finite interval Observable, then apply `combineAll`
* ```javascript
*
* ```ts
* import { fromEvent, interval } from 'rxjs';
* import { map, combineAll, take } from 'rxjs/operators';
* import { fromEvent } from 'rxjs/observable/fromEvent';
*
* const clicks = fromEvent(document, 'click');
* const higherOrder = clicks.pipe(
+1 -1
View File
@@ -25,5 +25,5 @@ export function concat<T, R>(...observables: Array<ObservableInput<any> | Schedu
* @deprecated Deprecated in favor of static {@link concat}.
*/
export function concat<T, R>(...observables: Array<ObservableInput<any> | SchedulerLike>): OperatorFunction<T, R> {
return (source: Observable<T>) => source.lift.call(concatStatic<T, R>(source, ...observables));
return (source: Observable<T>) => source.lift.call(concatStatic(source, ...observables));
}
+4 -1
View File
@@ -30,7 +30,10 @@ export function concatAll<R>(): OperatorFunction<any, R>;
* ## Example
*
* For each click event, tick every second from 0 to 3, with no concurrency
* ```javascript
* ```ts
* import { fromEvent, interval } from 'rxjs';
* import { map, take, concatAll } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const higherOrder = clicks.pipe(
* map(ev => interval(1000).pipe(take(4))),
+13 -10
View File
@@ -1,12 +1,12 @@
import { mergeMap } from './mergeMap';
import { ObservableInput, OperatorFunction } from '../types';
import { ObservableInput, OperatorFunction, ObservedValueOf } from '../types';
/* tslint:disable:max-line-length */
export function concatMap<T, R>(project: (value: T, index: number) => ObservableInput<R>): OperatorFunction<T, R>;
export function concatMap<T, O extends ObservableInput<any>>(project: (value: T, index: number) => O): OperatorFunction<T, ObservedValueOf<O>>;
/** @deprecated resultSelector no longer supported, use inner map instead */
export function concatMap<T, R>(project: (value: T, index: number) => ObservableInput<R>, resultSelector: undefined): OperatorFunction<T, R>;
export function concatMap<T, O extends ObservableInput<any>>(project: (value: T, index: number) => O, resultSelector: undefined): OperatorFunction<T, ObservedValueOf<O>>;
/** @deprecated resultSelector no longer supported, use inner map instead */
export function concatMap<T, I, R>(project: (value: T, index: number) => ObservableInput<I>, resultSelector: (outerValue: T, innerValue: I, outerIndex: number, innerIndex: number) => R): OperatorFunction<T, R>;
export function concatMap<T, R, O extends ObservableInput<any>>(project: (value: T, index: number) => O, resultSelector: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R): OperatorFunction<T, R>;
/* tslint:enable:max-line-length */
/**
@@ -35,10 +35,13 @@ export function concatMap<T, I, R>(project: (value: T, index: number) => Observ
* ## Example
* For each click event, tick every second from 0 to 3, with no concurrency
*
* ```javascript
* ```ts
* import { fromEvent, interval } from 'rxjs';
* import { concatMap, take } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const result = clicks.pipe(
* concatMap(ev => interval(1000).pipe(take(4)),
* concatMap(ev => interval(1000).pipe(take(4)))
* );
* result.subscribe(x => console.log(x));
*
@@ -66,9 +69,9 @@ export function concatMap<T, I, R>(project: (value: T, index: number) => Observ
* @method concatMap
* @owner Observable
*/
export function concatMap<T, I, R>(
project: (value: T, index: number) => ObservableInput<I>,
resultSelector?: (outerValue: T, innerValue: I, outerIndex: number, innerIndex: number) => R
): OperatorFunction<T, I|R> {
export function concatMap<T, R, O extends ObservableInput<any>>(
project: (value: T, index: number) => O,
resultSelector?: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R
): OperatorFunction<T, ObservedValueOf<O>|R> {
return mergeMap(project, resultSelector, 1);
}
+12 -9
View File
@@ -1,12 +1,12 @@
import { concatMap } from './concatMap';
import { ObservableInput, OperatorFunction } from '../types';
import { ObservableInput, OperatorFunction, ObservedValueOf } from '../types';
/* tslint:disable:max-line-length */
export function concatMapTo<T>(observable: ObservableInput<T>): OperatorFunction<any, T>;
export function concatMapTo<T, O extends ObservableInput<any>>(observable: O): OperatorFunction<T, ObservedValueOf<O>>;
/** @deprecated */
export function concatMapTo<T>(observable: ObservableInput<T>, resultSelector: undefined): OperatorFunction<any, T>;
export function concatMapTo<T, O extends ObservableInput<any>>(observable: O, resultSelector: undefined): OperatorFunction<T, ObservedValueOf<O>>;
/** @deprecated */
export function concatMapTo<T, I, R>(observable: ObservableInput<I>, resultSelector: (outerValue: T, innerValue: I, outerIndex: number, innerIndex: number) => R): OperatorFunction<T, R>;
export function concatMapTo<T, R, O extends ObservableInput<any>>(observable: O, resultSelector: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R): OperatorFunction<T, R>;
/* tslint:enable:max-line-length */
/**
@@ -34,7 +34,10 @@ export function concatMapTo<T, I, R>(observable: ObservableInput<I>, resultSelec
*
* ## Example
* For each click event, tick every second from 0 to 3, with no concurrency
* ```javascript
* ```ts
* import { fromEvent, interval } from 'rxjs';
* import { concatMapTo, take } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const result = clicks.pipe(
* concatMapTo(interval(1000).pipe(take(4))),
@@ -62,9 +65,9 @@ export function concatMapTo<T, I, R>(observable: ObservableInput<I>, resultSelec
* @method concatMapTo
* @owner Observable
*/
export function concatMapTo<T, I, R>(
innerObservable: ObservableInput<I>,
resultSelector?: (outerValue: T, innerValue: I, outerIndex: number, innerIndex: number) => R
): OperatorFunction<T, R> {
export function concatMapTo<T, R, O extends ObservableInput<any>>(
innerObservable: O,
resultSelector?: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R
): OperatorFunction<T, ObservedValueOf<O>|R> {
return concatMap(() => innerObservable, resultSelector);
}
+8 -2
View File
@@ -23,7 +23,10 @@ import { Subscriber } from '../Subscriber';
* ## Examples
*
* Counts how many seconds have passed before the first click happened
* ```javascript
* ```ts
* import { fromEvent, interval } from 'rxjs';
* import { count, takeUntil } from 'rxjs/operators';
*
* const seconds = interval(1000);
* const clicks = fromEvent(document, 'click');
* const secondsBeforeClick = seconds.pipe(takeUntil(clicks));
@@ -32,7 +35,10 @@ import { Subscriber } from '../Subscriber';
* ```
*
* Counts how many odd numbers are there between 1 and 7
* ```javascript
* ```ts
* import { range } from 'rxjs';
* import { count } from 'rxjs/operators';
*
* const numbers = range(1, 7);
* const result = numbers.pipe(count(i => i % 2 === 1));
* result.subscribe(x => console.log(x));
+4 -1
View File
@@ -33,7 +33,10 @@ import { subscribeToResult } from '../util/subscribeToResult';
*
* ## Example
* Emit the most recent click after a burst of clicks
* ```javascript
* ```ts
* import { fromEvent, interval } from 'rxjs';
* import { debounce } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const result = clicks.pipe(debounce(() => interval(1000)));
* result.subscribe(x => console.log(x));
+4 -1
View File
@@ -30,7 +30,10 @@ import { MonoTypeOperatorFunction, SchedulerLike, TeardownLogic } from '../types
*
* ## Example
* Emit the most recent click after a burst of clicks
* ```javascript
* ```ts
* import { fromEvent } from 'rxjs';
* import { debounceTime } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const result = clicks.pipe(debounceTime(1000));
* result.subscribe(x => console.log(x));
+4 -1
View File
@@ -23,7 +23,10 @@ export function defaultIfEmpty<T, R>(defaultValue?: R): OperatorFunction<T, T |
*
* ## Example
* If no clicks happen in 5 seconds, then emit "no clicks"
* ```javascript
* ```ts
* import { fromEvent } from 'rxjs';
* import { defaultIfEmpty, takeUntil } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const clicksBeforeFive = clicks.pipe(takeUntil(interval(5000)));
* const result = clicksBeforeFive.pipe(defaultIfEmpty('no clicks'));
+8 -2
View File
@@ -25,14 +25,20 @@ import { MonoTypeOperatorFunction, PartialObserver, SchedulerAction, SchedulerLi
*
* ## Examples
* Delay each click by one second
* ```javascript
* ```ts
* import { fromEvent } from 'rxjs';
* import { delay } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const delayedClicks = clicks.pipe(delay(1000)); // each click emitted after 1 second
* delayedClicks.subscribe(x => console.log(x));
* ```
*
* Delay all clicks until a future date happens
* ```javascript
* ```ts
* import { fromEvent } from 'rxjs';
* import { delay } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const date = new Date('March 15, 2050 12:00:00'); // in the future
* const delayedClicks = clicks.pipe(delay(date)); // click emitted only after that date
+4 -1
View File
@@ -40,7 +40,10 @@ export function delayWhen<T>(delayDurationSelector: (value: T, index: number) =>
*
* ## Example
* Delay each click by a random amount of time, between 0 and 5 seconds
* ```javascript
* ```ts
* import { fromEvent, interval } from 'rxjs';
* import { delayWhen } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const delayedClicks = clicks.pipe(
* delayWhen(event => interval(Math.random() * 5000)),
+4 -1
View File
@@ -23,7 +23,10 @@ import { OperatorFunction } from '../types';
*
* ## Example
* Convert an Observable of Notifications to an actual Observable
* ```javascript
* ```ts
* import { of, Notification } from 'rxjs';
* import { dematerialize } from 'rxjs/operators';
*
* const notifA = new Notification('N', 'A');
* const notifB = new Notification('N', 'B');
* const notifE = new Notification('E', undefined,
+7 -1
View File
@@ -22,7 +22,10 @@ import { MonoTypeOperatorFunction, TeardownLogic } from '../types';
*
* ## Examples
* A simple example with numbers
* ```javascript
* ```ts
* import { of } from 'rxjs';
* import { distinct } from 'rxjs/operators';
*
* of(1, 1, 2, 2, 2, 1, 2, 3, 4, 3, 2, 1).pipe(
* distinct(),
* )
@@ -31,6 +34,9 @@ import { MonoTypeOperatorFunction, TeardownLogic } from '../types';
*
* An example using a keySelector function
* ```typescript
* import { of } from 'rxjs';
* import { distinct } from 'rxjs/operators';
*
* interface Person {
* age: number,
* name: string
+24 -21
View File
@@ -1,7 +1,5 @@
import { Operator } from '../Operator';
import { Subscriber } from '../Subscriber';
import { tryCatch } from '../util/tryCatch';
import { errorObject } from '../util/errorObject';
import { Observable } from '../Observable';
import { MonoTypeOperatorFunction, TeardownLogic } from '../types';
@@ -13,13 +11,19 @@ export function distinctUntilChanged<T, K>(compare: (x: K, y: K) => boolean, key
/**
* Returns an Observable that emits all items emitted by the source Observable that are distinct by comparison from the previous item.
*
* If a comparator function is provided, then it will be called for each item to test for whether or not that value should be emitted.
* <span class="informal">It's like {@link filter}, but just emits the values that are distinct from the previous.</span>
*
* ![](distinctUntilChanged.png)
*
* If a comparator function is provided, then it will be called for each item to test for whether or not that value should be emitted.
* If a comparator function is not provided, an equality check is used by default.
*
* ## Example
* A simple example with numbers
* ```javascript
* ```ts
* import { of } from 'rxjs';
* import { distinctUntilChanged } from 'rxjs/operators';
*
* of(1, 1, 2, 2, 2, 1, 1, 2, 3, 3, 4).pipe(
* distinctUntilChanged(),
* )
@@ -28,6 +32,9 @@ export function distinctUntilChanged<T, K>(compare: (x: K, y: K) => boolean, key
*
* An example using a compare function
* ```typescript
* import { of } from 'rxjs';
* import { distinctUntilChanged } from 'rxjs/operators';
*
* interface Person {
* age: number,
* name: string
@@ -94,29 +101,25 @@ class DistinctUntilChangedSubscriber<T, K> extends Subscriber<T> {
}
protected _next(value: T): void {
const keySelector = this.keySelector;
let key: any = value;
if (keySelector) {
key = tryCatch(this.keySelector)(value);
if (key === errorObject) {
return this.destination.error(errorObject.e);
}
let key: any;
try {
const { keySelector } = this;
key = keySelector ? keySelector(value) : value;
} catch (err) {
return this.destination.error(err);
}
let result: any = false;
let result = false;
if (this.hasKey) {
result = tryCatch(this.compare)(this.key, key);
if (result === errorObject) {
return this.destination.error(errorObject.e);
try {
const { compare } = this;
result = compare(this.key, key);
} catch (err) {
return this.destination.error(err);
}
} else {
this.hasKey = true;
}
if (Boolean(result) === false) {
if (!result) {
this.key = key;
this.destination.next(value);
}
+13 -2
View File
@@ -10,13 +10,21 @@ export function distinctUntilKeyChanged<T, K extends keyof T>(key: K, compare: (
* Returns an Observable that emits all items emitted by the source Observable that are distinct by comparison from the previous item,
* using a property accessed by using the key provided to check if the two items are distinct.
*
* If a comparator function is provided, then it will be called for each item to test for whether or not that value should be emitted.
* <span class="informal">It's like {@link distinctUntilChanged}, but the distinct comparison uses a key to access a property.</span>
*
* If a comparator function is not provided, an equality check is used by default.
* ![](distinctUntilKeyChanged.png)
*
* `distinctUntilKeyChanged` emits all items of the source Observable, wich are distinct by comparison.
* The comparison checks if the previous item is distinct from the current item, using a `key` to access a property.
* If a comparator function is provided, then it will be called for each item with the property key
* to test for whether or not that value should be emitted.
*
* ## Examples
* An example comparing the name of persons
* ```typescript
* import { of } from 'rxjs';
* import { distinctUntilKeyChanged } from 'rxjs/operators';
*
* interface Person {
* age: number,
* name: string
@@ -40,6 +48,9 @@ export function distinctUntilKeyChanged<T, K extends keyof T>(key: K, compare: (
*
* An example comparing the first letters of the name
* ```typescript
* import { of } from 'rxjs';
* import { distinctUntilKeyChanged } from 'rxjs/operators';
*
* interface Person {
* age: number,
* name: string
+4 -1
View File
@@ -24,7 +24,10 @@ import { take } from './take';
*
* ## Example
* Emit only the third click event
* ```javascript
* ```ts
* import { fromEvent } from 'rxjs';
* import { elementAt } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const result = clicks.pipe(elementAt(2));
* result.subscribe(x => console.log(x));
+32 -32
View File
@@ -1,20 +1,33 @@
import { Observable } from '../Observable';
import { fromArray } from '../observable/fromArray';
import { scalar } from '../observable/scalar';
import { empty } from '../observable/empty';
import { concat as concatStatic } from '../observable/concat';
import { isScheduler } from '../util/isScheduler';
import { MonoTypeOperatorFunction, SchedulerLike } from '../types';
import { concat } from '../observable/concat';
import { of } from '../observable/of';
import { MonoTypeOperatorFunction, SchedulerLike, OperatorFunction } from '../types';
/* tslint:disable:max-line-length */
export function endWith<T>(scheduler?: SchedulerLike): MonoTypeOperatorFunction<T>;
export function endWith<T>(v1: T, scheduler?: SchedulerLike): MonoTypeOperatorFunction<T>;
export function endWith<T>(v1: T, v2: T, scheduler?: SchedulerLike): MonoTypeOperatorFunction<T>;
export function endWith<T>(v1: T, v2: T, v3: T, scheduler?: SchedulerLike): MonoTypeOperatorFunction<T>;
export function endWith<T>(v1: T, v2: T, v3: T, v4: T, scheduler?: SchedulerLike): MonoTypeOperatorFunction<T>;
export function endWith<T>(v1: T, v2: T, v3: T, v4: T, v5: T, scheduler?: SchedulerLike): MonoTypeOperatorFunction<T>;
export function endWith<T>(v1: T, v2: T, v3: T, v4: T, v5: T, v6: T, scheduler?: SchedulerLike): MonoTypeOperatorFunction<T>;
export function endWith<T>(...array: Array<T | SchedulerLike>): MonoTypeOperatorFunction<T>;
/** @deprecated use {@link scheduled} and {@link concatAll} (e.g. `scheduled([source, [a, b, c]], scheduler).pipe(concatAll())`) */
export function endWith<T>(scheduler: SchedulerLike): MonoTypeOperatorFunction<T>;
/** @deprecated use {@link scheduled} and {@link concatAll} (e.g. `scheduled([source, [a, b, c]], scheduler).pipe(concatAll())`) */
export function endWith<T, A>(v1: A, scheduler: SchedulerLike): OperatorFunction<T, T | A>;
/** @deprecated use {@link scheduled} and {@link concatAll} (e.g. `scheduled([source, [a, b, c]], scheduler).pipe(concatAll())`) */
export function endWith<T, A, B>(v1: A, v2: B, scheduler: SchedulerLike): OperatorFunction<T, T | A | B>;
/** @deprecated use {@link scheduled} and {@link concatAll} (e.g. `scheduled([source, [a, b, c]], scheduler).pipe(concatAll())`) */
export function endWith<T, A, B, C>(v1: A, v2: B, v3: C, scheduler: SchedulerLike): OperatorFunction<T, T | A | B | C>;
/** @deprecated use {@link scheduled} and {@link concatAll} (e.g. `scheduled([source, [a, b, c]], scheduler).pipe(concatAll())`) */
export function endWith<T, A, B, C, D>(v1: A, v2: B, v3: C, v4: D, scheduler: SchedulerLike): OperatorFunction<T, T | A | B | C | D>;
/** @deprecated use {@link scheduled} and {@link concatAll} (e.g. `scheduled([source, [a, b, c]], scheduler).pipe(concatAll())`) */
export function endWith<T, A, B, C, D, E>(v1: A, v2: B, v3: C, v4: D, v5: E, scheduler: SchedulerLike): OperatorFunction<T, T | A | B | C | D | E>;
/** @deprecated use {@link scheduled} and {@link concatAll} (e.g. `scheduled([source, [a, b, c]], scheduler).pipe(concatAll())`) */
export function endWith<T, A, B, C, D, E, F>(v1: A, v2: B, v3: C, v4: D, v5: E, v6: F, scheduler: SchedulerLike): OperatorFunction<T, T | A | B | C | D | E | F>;
export function endWith<T, A>(v1: A): OperatorFunction<T, T | A>;
export function endWith<T, A, B>(v1: A, v2: B): OperatorFunction<T, T | A | B>;
export function endWith<T, A, B, C>(v1: A, v2: B, v3: C): OperatorFunction<T, T | A | B | C>;
export function endWith<T, A, B, C, D>(v1: A, v2: B, v3: C, v4: D): OperatorFunction<T, T | A | B | C | D>;
export function endWith<T, A, B, C, D, E>(v1: A, v2: B, v3: C, v4: D, v5: E): OperatorFunction<T, T | A | B | C | D | E>;
export function endWith<T, A, B, C, D, E, F>(v1: A, v2: B, v3: C, v4: D, v5: E, v6: F): OperatorFunction<T, T | A | B | C | D | E | F>;
export function endWith<T, Z = T>(...array: Z[]): OperatorFunction<T, T | Z>;
/** @deprecated use {@link scheduled} and {@link concatAll} (e.g. `scheduled([source, [a, b, c]], scheduler).pipe(concatAll())`) */
export function endWith<T, Z = T>(...array: Array<Z | SchedulerLike>): OperatorFunction<T, T | Z>;
/* tslint:enable:max-line-length */
/**
@@ -26,7 +39,10 @@ export function endWith<T>(...array: Array<T | SchedulerLike>): MonoTypeOperator
* ## Example
* ### After the source observable completes, appends an emission and then completes too.
*
* ```javascript
* ```ts
* import { of } from 'rxjs';
* import { endWith } from 'rxjs/operators';
*
* of('hi', 'how are you?', 'sorry, I have to go now').pipe(
* endWith('goodbye!'),
* )
@@ -47,21 +63,5 @@ export function endWith<T>(...array: Array<T | SchedulerLike>): MonoTypeOperator
* @owner Observable
*/
export function endWith<T>(...array: Array<T | SchedulerLike>): MonoTypeOperatorFunction<T> {
return (source: Observable<T>) => {
let scheduler = <SchedulerLike>array[array.length - 1];
if (isScheduler(scheduler)) {
array.pop();
} else {
scheduler = null;
}
const len = array.length;
if (len === 1 && !scheduler) {
return concatStatic(source, scalar(array[0] as T));
} else if (len > 0) {
return concatStatic(source, fromArray(array as T[], scheduler));
} else {
return concatStatic<T>(source, empty(scheduler) as any);
}
};
return (source: Observable<T>) => concat(source, of(...array)) as Observable<T>;
}
+4 -1
View File
@@ -8,7 +8,10 @@ import { Observer, OperatorFunction } from '../types';
*
* ## Example
* A simple example emitting true if all elements are less than 5, false otherwise
* ```javascript
* ```ts
* import { of } from 'rxjs';
* import { every } from 'rxjs/operators';
*
* of(1, 2, 3, 4, 5, 6).pipe(
* every(x => x < 5),
* )
+4 -1
View File
@@ -28,7 +28,10 @@ export function exhaust<R>(): OperatorFunction<any, R>;
*
* ## Example
* Run a finite timer for each click, only if there is no currently active timer
* ```javascript
* ```ts
* import { fromEvent, interval } from 'rxjs';
* import { exhaust, map, take } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const higherOrder = clicks.pipe(
* map((ev) => interval(1000).pipe(take(5))),
+15 -12
View File
@@ -5,14 +5,14 @@ import { Subscription } from '../Subscription';
import { OuterSubscriber } from '../OuterSubscriber';
import { InnerSubscriber } from '../InnerSubscriber';
import { subscribeToResult } from '../util/subscribeToResult';
import { ObservableInput, OperatorFunction } from '../types';
import { ObservableInput, OperatorFunction, ObservedValueOf } from '../types';
import { map } from './map';
import { from } from '../observable/from';
/* tslint:disable:max-line-length */
export function exhaustMap<T, R>(project: (value: T, index: number) => ObservableInput<R>): OperatorFunction<T, R>;
export function exhaustMap<T, O extends ObservableInput<any>>(project: (value: T, index: number) => O): OperatorFunction<T, ObservedValueOf<O>>;
/** @deprecated resultSelector is no longer supported. Use inner map instead. */
export function exhaustMap<T, R>(project: (value: T, index: number) => ObservableInput<R>, resultSelector: undefined): OperatorFunction<T, R>;
export function exhaustMap<T, O extends ObservableInput<any>>(project: (value: T, index: number) => O, resultSelector: undefined): OperatorFunction<T, ObservedValueOf<O>>;
/** @deprecated resultSelector is no longer supported. Use inner map instead. */
export function exhaustMap<T, I, R>(project: (value: T, index: number) => ObservableInput<I>, resultSelector: (outerValue: T, innerValue: I, outerIndex: number, innerIndex: number) => R): OperatorFunction<T, R>;
/* tslint:enable:max-line-length */
@@ -37,10 +37,13 @@ export function exhaustMap<T, I, R>(project: (value: T, index: number) => Observ
*
* ## Example
* Run a finite timer for each click, only if there is no currently active timer
* ```javascript
* ```ts
* import { fromEvent, interval } from 'rxjs';
* import { exhaustMap, take } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const result = clicks.pipe(
* exhaustMap((ev) => interval(1000).pipe(take(5))),
* exhaustMap(ev => interval(1000).pipe(take(5)))
* );
* result.subscribe(x => console.log(x));
* ```
@@ -59,23 +62,23 @@ export function exhaustMap<T, I, R>(project: (value: T, index: number) => Observ
* @method exhaustMap
* @owner Observable
*/
export function exhaustMap<T, I, R>(
project: (value: T, index: number) => ObservableInput<I>,
resultSelector?: (outerValue: T, innerValue: I, outerIndex: number, innerIndex: number) => R,
): OperatorFunction<T, I|R> {
export function exhaustMap<T, R, O extends ObservableInput<any>>(
project: (value: T, index: number) => O,
resultSelector?: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R,
): OperatorFunction<T, ObservedValueOf<O>|R> {
if (resultSelector) {
// DEPRECATED PATH
return (source: Observable<T>) => source.pipe(
exhaustMap((a, i) => from(project(a, i)).pipe(
map((b, ii) => resultSelector(a, b, i, ii)),
map((b: any, ii: any) => resultSelector(a, b, i, ii)),
)),
);
}
return (source: Observable<T>) =>
source.lift(new ExhauseMapOperator(project));
source.lift(new ExhaustMapOperator(project));
}
class ExhauseMapOperator<T, R> implements Operator<T, R> {
class ExhaustMapOperator<T, R> implements Operator<T, R> {
constructor(private project: (value: T, index: number) => ObservableInput<R>) {
}
+16 -12
View File
@@ -1,8 +1,6 @@
import { Observable } from '../Observable';
import { Operator } from '../Operator';
import { Subscriber } from '../Subscriber';
import { tryCatch } from '../util/tryCatch';
import { errorObject } from '../util/errorObject';
import { Subscription } from '../Subscription';
import { OuterSubscriber } from '../OuterSubscriber';
import { InnerSubscriber } from '../InnerSubscriber';
@@ -36,7 +34,10 @@ export function expand<T>(project: (value: T, index: number) => ObservableInput<
*
* ## Example
* Start emitting the powers of two on every click, at most 10 of them
* ```javascript
* ```ts
* import { fromEvent, of } from 'rxjs';
* import { expand, mapTo, delay, take } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const powersOfTwo = clicks.pipe(
* mapTo(1),
@@ -126,15 +127,18 @@ export class ExpandSubscriber<T, R> extends OuterSubscriber<T, R> {
const index = this.index++;
if (this.active < this.concurrent) {
destination.next(value);
let result = tryCatch(this.project)(value, index);
if (result === errorObject) {
destination.error(errorObject.e);
} else if (!this.scheduler) {
this.subscribeToProjection(result, value, index);
} else {
const state: DispatchArg<T, R> = { subscriber: this, result, value, index };
const destination = this.destination as Subscription;
destination.add(this.scheduler.schedule<DispatchArg<T, R>>(ExpandSubscriber.dispatch, 0, state));
try {
const { project } = this;
const result = project(value, index);
if (!this.scheduler) {
this.subscribeToProjection(result, value, index);
} else {
const state: DispatchArg<T, R> = { subscriber: this, result, value, index };
const destination = this.destination as Subscription;
destination.add(this.scheduler.schedule<DispatchArg<T, R>>(ExpandSubscriber.dispatch, 0, state));
}
} catch (e) {
destination.error(e);
}
} else {
this.buffer.push(value);
+4 -1
View File
@@ -26,7 +26,10 @@ export function filter<T>(predicate: (value: T, index: number) => boolean,
*
* ## Example
* Emit only click events whose target was a DIV element
* ```javascript
* ```ts
* import { fromEvent } from 'rxjs';
* import { filter } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const clicksOnDivs = clicks.pipe(filter(ev => ev.target.tagName === 'DIV'));
* clicksOnDivs.subscribe(x => console.log(x));
+4 -1
View File
@@ -23,7 +23,10 @@ export function find<T>(predicate: (value: T, index: number, source: Observable<
*
* ## Example
* Find and emit the first click that happens on a DIV element
* ```javascript
* ```ts
* import { fromEvent } from 'rxjs';
* import { find } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const result = clicks.pipe(find(ev => ev.target.tagName === 'DIV'));
* result.subscribe(x => console.log(x));
+4 -1
View File
@@ -18,7 +18,10 @@ import { OperatorFunction } from '../types';
*
* ## Example
* Emit the index of first click that happens on a DIV element
* ```javascript
* ```ts
* import { fromEvent } from 'rxjs';
* import { findIndex } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const result = clicks.pipe(findIndex(ev => ev.target.tagName === 'DIV'));
* result.subscribe(x => console.log(x));
+8 -2
View File
@@ -43,14 +43,20 @@ export function first<T, D = T>(
*
* ## Examples
* Emit only the first click that happens on the DOM
* ```javascript
* ```ts
* import { fromEvent } from 'rxjs';
* import { first } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const result = clicks.pipe(first());
* result.subscribe(x => console.log(x));
* ```
*
* Emits the first click that happens on a DIV
* ```javascript
* ```ts
* import { fromEvent } from 'rxjs';
* import { first } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const result = clicks.pipe(first(ev => ev.target.tagName === 'DIV'));
* result.subscribe(x => console.log(x));
+34 -33
View File
@@ -31,22 +31,19 @@ export function groupBy<T, K, R>(keySelector: (value: T) => K, elementSelector?:
* returned by the elementSelector function.
*
* ## Examples
*
* ### Group objects by id and return as array
* ```javascript
* import { mergeMap, groupBy } from 'rxjs/operators';
* import { of } from 'rxjs/observable/of';
*
* interface Obj {
* id: number,
* name: string,
* }
* ```ts
* import { of } from 'rxjs';
* import { mergeMap, groupBy, reduce } from 'rxjs/operators';
*
* of<Obj>(
* {id: 1, name: 'javascript'},
* {id: 2, name: 'parcel'},
* of(
* {id: 1, name: 'JavaScript'},
* {id: 2, name: 'Parcel'},
* {id: 2, name: 'webpack'},
* {id: 1, name: 'typescript'},
* {id: 3, name: 'tslint'}
* {id: 1, name: 'TypeScript'},
* {id: 3, name: 'TSLint'}
* ).pipe(
* groupBy(p => p.id),
* mergeMap((group$) => group$.pipe(reduce((acc, cur) => [...acc, cur], []))),
@@ -54,37 +51,41 @@ export function groupBy<T, K, R>(keySelector: (value: T) => K, elementSelector?:
* .subscribe(p => console.log(p));
*
* // displays:
* // [ { id: 1, name: 'javascript'},
* // { id: 1, name: 'typescript'} ]
* // [ { id: 1, name: 'JavaScript'},
* // { id: 1, name: 'TypeScript'} ]
* //
* // [ { id: 2, name: 'parcel'},
* // [ { id: 2, name: 'Parcel'},
* // { id: 2, name: 'webpack'} ]
* //
* // [ { id: 3, name: 'tslint'} ]
* // [ { id: 3, name: 'TSLint'} ]
* ```
*
* ### Pivot data on the id field
* ```javascript
* import { mergeMap, groupBy, map } from 'rxjs/operators';
* import { of } from 'rxjs/observable/of';
*
* of<Obj>(
* {id: 1, name: 'javascript'},
* {id: 2, name: 'parcel'},
* {id: 2, name: 'webpack'},
* {id: 1, name: 'typescript'}
* {id: 3, name: 'tslint'}
* ).pipe(
* groupBy(p => p.id, p => p.name),
* mergeMap( (group$) => group$.pipe(reduce((acc, cur) => [...acc, cur], ["" + group$.key]))),
* map(arr => ({'id': parseInt(arr[0]), 'values': arr.slice(1)})),
* ```ts
* import { of } from 'rxjs';
* import { groupBy, map, mergeMap, reduce } from 'rxjs/operators';
*
* of(
* { id: 1, name: 'JavaScript' },
* { id: 2, name: 'Parcel' },
* { id: 2, name: 'webpack' },
* { id: 1, name: 'TypeScript' },
* { id: 3, name: 'TSLint' }
* )
* .subscribe(p => console.log(p));
* .pipe(
* groupBy(p => p.id, p => p.name),
* mergeMap(group$ =>
* group$.pipe(reduce((acc, cur) => [...acc, cur], [`${group$.key}`]))
* ),
* map(arr => ({ id: parseInt(arr[0], 10), values: arr.slice(1) }))
* )
* .subscribe(p => console.log(p));
*
* // displays:
* // { id: 1, values: [ 'javascript', 'typescript' ] }
* // { id: 2, values: [ 'parcel', 'webpack' ] }
* // { id: 3, values: [ 'tslint' ] }
* // { id: 1, values: [ 'JavaScript', 'TypeScript' ] }
* // { id: 2, values: [ 'Parcel', 'webpack' ] }
* // { id: 3, values: [ 'TSLint' ] }
* ```
*
* @param {function(value: T): K} keySelector A function that extracts the key
+4 -1
View File
@@ -10,7 +10,10 @@ import { OperatorFunction } from '../types';
*
* ## Examples
* ### Ignores emitted values, reacts to observable's completion.
* ```javascript
* ```ts
* import { of } from 'rxjs';
* import { ignoreElements } from 'rxjs/operators';
*
* of('you', 'talking', 'to', 'me').pipe(
* ignoreElements(),
* )
+60
View File
@@ -3,6 +3,66 @@ import { Subscriber } from '../Subscriber';
import { Observable } from '../Observable';
import { OperatorFunction } from '../types';
/**
* Emits false if the input observable emits any values, or emits true if the
* input observable completes without emitting any values.
*
* <span class="informal">Tells whether any values are emitted by an observable</span>
*
* ![](isEmpty.png)
*
* `isEmpty` transforms an Observable that emits values into an Observable that
* emits a single boolean value representing whether or not any values were
* emitted by the source Observable. As soon as the source Observable emits a
* value, `isEmpty` will emit a `false` and complete. If the source Observable
* completes having not emitted anything, `isEmpty` will emit a `true` and
* complete.
*
* A similar effect could be achieved with {@link count}, but `isEmpty` can emit
* a `false` value sooner.
*
* ## Examples
*
* Emit `false` for a non-empty Observable
* ```javascript
* import { Subject } from 'rxjs';
* import { isEmpty } from 'rxjs/operators';
*
* const source = new Subject<string>();
* const result = source.pipe(isEmpty());
* source.subscribe(x => console.log(x));
* result.subscribe(x => console.log(x));
* source.next('a');
* source.next('b');
* source.next('c');
* source.complete();
*
* // Results in:
* // a
* // false
* // b
* // c
* ```
*
* Emit `true` for an empty Observable
* ```javascript
* import { EMPTY } from 'rxjs';
* import { isEmpty } from 'rxjs/operators';
*
* const result = EMPTY.pipe(isEmpty());
* result.subscribe(x => console.log(x));
* // Results in:
* // true
* ```
*
* @see {@link count}
* @see {@link EMPTY}
*
* @return {OperatorFunction<T, boolean>} An Observable of a boolean value indicating whether observable was empty or not
* @method isEmpty
* @owner Observable
*/
export function isEmpty<T>(): OperatorFunction<T, boolean> {
return (source: Observable<T>) => source.lift(new IsEmptyOperator());
}
+4 -1
View File
@@ -19,7 +19,10 @@ import { OperatorFunction } from '../types';
*
* ## Example
* Map every click to the clientX position of that click
* ```javascript
* ```ts
* import { fromEvent } from 'rxjs';
* import { map } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const positions = clicks.pipe(map(ev => ev.clientX));
* positions.subscribe(x => console.log(x));
+4 -1
View File
@@ -18,7 +18,10 @@ import { OperatorFunction } from '../types';
*
* ## Example
* Map every click to the string 'Hi'
* ```javascript
* ```ts
* import { fromEvent } from 'rxjs';
* import { mapTo } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const greetings = clicks.pipe(mapTo('Hi'));
* greetings.subscribe(x => console.log(x));
+4 -1
View File
@@ -28,7 +28,10 @@ import { OperatorFunction } from '../types';
*
* ## Example
* Convert a faulty Observable to an Observable of Notifications
* ```javascript
* ```ts
* import { of } from 'rxjs';
* import { materialize, map } from 'rxjs/operators';
*
* const letters = of('a', 'b', 13, 'd');
* const upperCase = letters.pipe(map(x => x.toUpperCase()));
* const materialized = upperCase.pipe(materialize());
+7 -1
View File
@@ -9,7 +9,10 @@ import { MonoTypeOperatorFunction } from '../types';
*
* ## Examples
* Get the maximal value of a series of numbers
* ```javascript
* ```ts
* import { of } from 'rxjs';
* import { max } from 'rxjs/operators';
*
* of(5, 4, 7, 2, 8).pipe(
* max(),
* )
@@ -18,6 +21,9 @@ import { MonoTypeOperatorFunction } from '../types';
*
* Use a comparer function to get the maximal item
* ```typescript
* import { of } from 'rxjs';
* import { max } from 'rxjs/operators';
*
* interface Person {
* age: number,
* name: string
+11 -7
View File
@@ -1,9 +1,7 @@
import { mergeMap } from './mergeMap';
import { identity } from '../util/identity';
import { MonoTypeOperatorFunction, OperatorFunction, ObservableInput } from '../types';
export function mergeAll<T>(concurrent?: number): OperatorFunction<ObservableInput<T>, T>;
import { OperatorFunction, ObservableInput } from '../types';
/**
* Converts a higher-order Observable into a first-order Observable which
@@ -22,7 +20,10 @@ export function mergeAll<T>(concurrent?: number): OperatorFunction<ObservableInp
*
* ## Examples
* Spawn a new interval Observable for each click event, and blend their outputs as one Observable
* ```javascript
* ```ts
* import { fromEvent, interval } from 'rxjs';
* import { map, mergeAll } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const higherOrder = clicks.pipe(map((ev) => interval(1000)));
* const firstOrder = higherOrder.pipe(mergeAll());
@@ -30,7 +31,10 @@ export function mergeAll<T>(concurrent?: number): OperatorFunction<ObservableInp
* ```
*
* Count from 0 to 9 every second for each click, but only allow 2 concurrent timers
* ```javascript
* ```ts
* import { fromEvent, interval } from 'rxjs';
* import { take, map, mergeAll } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const higherOrder = clicks.pipe(
* map((ev) => interval(1000).pipe(take(10))),
@@ -57,6 +61,6 @@ export function mergeAll<T>(concurrent?: number): OperatorFunction<ObservableInp
* @method mergeAll
* @owner Observable
*/
export function mergeAll<T>(concurrent: number = Number.POSITIVE_INFINITY): MonoTypeOperatorFunction<T> {
return mergeMap<T, T>(identity as (value: T, index: number) => ObservableInput<T>, concurrent);
export function mergeAll<T>(concurrent: number = Number.POSITIVE_INFINITY): OperatorFunction<ObservableInput<T>, T> {
return mergeMap(identity, concurrent);
}
+13 -10
View File
@@ -5,16 +5,16 @@ import { Subscription } from '../Subscription';
import { subscribeToResult } from '../util/subscribeToResult';
import { OuterSubscriber } from '../OuterSubscriber';
import { InnerSubscriber } from '../InnerSubscriber';
import { ObservableInput, OperatorFunction } from '../types';
import { ObservableInput, OperatorFunction, ObservedValueOf } from '../types';
import { map } from './map';
import { from } from '../observable/from';
/* tslint:disable:max-line-length */
export function mergeMap<T, R>(project: (value: T, index: number) => ObservableInput<R>, concurrent?: number): OperatorFunction<T, R>;
export function mergeMap<T, O extends ObservableInput<any>>(project: (value: T, index: number) => O, concurrent?: number): OperatorFunction<T, ObservedValueOf<O>>;
/** @deprecated resultSelector no longer supported, use inner map instead */
export function mergeMap<T, R>(project: (value: T, index: number) => ObservableInput<R>, resultSelector: undefined, concurrent?: number): OperatorFunction<T, R>;
export function mergeMap<T, O extends ObservableInput<any>>(project: (value: T, index: number) => O, resultSelector: undefined, concurrent?: number): OperatorFunction<T, ObservedValueOf<O>>;
/** @deprecated resultSelector no longer supported, use inner map instead */
export function mergeMap<T, I, R>(project: (value: T, index: number) => ObservableInput<I>, resultSelector: (outerValue: T, innerValue: I, outerIndex: number, innerIndex: number) => R, concurrent?: number): OperatorFunction<T, R>;
export function mergeMap<T, R, O extends ObservableInput<any>>(project: (value: T, index: number) => O, resultSelector: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R, concurrent?: number): OperatorFunction<T, R>;
/* tslint:enable:max-line-length */
/**
@@ -33,7 +33,10 @@ export function mergeMap<T, I, R>(project: (value: T, index: number) => Observab
*
* ## Example
* Map and flatten each letter to an Observable ticking every 1 second
* ```javascript
* ```ts
* import { of, interval } from 'rxjs';
* import { mergeMap, map } from 'rxjs/operators';
*
* const letters = of('a', 'b', 'c');
* const result = letters.pipe(
* mergeMap(x => interval(1000).pipe(map(i => x+i))),
@@ -70,16 +73,16 @@ export function mergeMap<T, I, R>(project: (value: T, index: number) => Observab
* @method mergeMap
* @owner Observable
*/
export function mergeMap<T, I, R>(
project: (value: T, index: number) => ObservableInput<I>,
resultSelector?: ((outerValue: T, innerValue: I, outerIndex: number, innerIndex: number) => R) | number,
export function mergeMap<T, R, O extends ObservableInput<any>>(
project: (value: T, index: number) => O,
resultSelector?: ((outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R) | number,
concurrent: number = Number.POSITIVE_INFINITY
): OperatorFunction<T, I|R> {
): OperatorFunction<T, ObservedValueOf<O>|R> {
if (typeof resultSelector === 'function') {
// DEPRECATED PATH
return (source: Observable<T>) => source.pipe(
mergeMap((a, i) => from(project(a, i)).pipe(
map((b, ii) => resultSelector(a, b, i, ii)),
map((b: any, ii: number) => resultSelector(a, b, i, ii)),
), concurrent)
);
} else if (typeof resultSelector === 'number') {
+11 -8
View File
@@ -1,12 +1,12 @@
import { Observable } from '../Observable';
import { OperatorFunction } from '../../internal/types';
import { OperatorFunction, ObservedValueOf } from '../../internal/types';
import { mergeMap } from './mergeMap';
import { ObservableInput } from '../types';
/* tslint:disable:max-line-length */
export function mergeMapTo<T>(innerObservable: ObservableInput<T>, concurrent?: number): OperatorFunction<any, T>;
export function mergeMapTo<T, O extends ObservableInput<any>>(innerObservable: O, concurrent?: number): OperatorFunction<any, ObservedValueOf<O>>;
/** @deprecated */
export function mergeMapTo<T, I, R>(innerObservable: ObservableInput<I>, resultSelector: (outerValue: T, innerValue: I, outerIndex: number, innerIndex: number) => R, concurrent?: number): OperatorFunction<T, R>;
export function mergeMapTo<T, R, O extends ObservableInput<any>>(innerObservable: O, resultSelector: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R, concurrent?: number): OperatorFunction<T, R>;
/* tslint:enable:max-line-length */
/**
@@ -24,7 +24,10 @@ export function mergeMapTo<T, I, R>(innerObservable: ObservableInput<I>, resultS
*
* ## Example
* For each click event, start an interval Observable ticking every 1 second
* ```javascript
* ```ts
* import { fromEvent, interval } from 'rxjs';
* import { mergeMapTo } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const result = clicks.pipe(mergeMapTo(interval(1000)));
* result.subscribe(x => console.log(x));
@@ -46,11 +49,11 @@ export function mergeMapTo<T, I, R>(innerObservable: ObservableInput<I>, resultS
* @method mergeMapTo
* @owner Observable
*/
export function mergeMapTo<T, I, R>(
innerObservable: ObservableInput<I>,
resultSelector?: ((outerValue: T, innerValue: I, outerIndex: number, innerIndex: number) => R) | number,
export function mergeMapTo<T, R, O extends ObservableInput<any>>(
innerObservable: O,
resultSelector?: ((outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R) | number,
concurrent: number = Number.POSITIVE_INFINITY
): OperatorFunction<T, I|R> {
): OperatorFunction<T, ObservedValueOf<O>|R> {
if (typeof resultSelector === 'function') {
return mergeMap(() => innerObservable, resultSelector, concurrent);
}
+19 -16
View File
@@ -2,8 +2,6 @@ import { Operator } from '../Operator';
import { Observable } from '../Observable';
import { Subscriber } from '../Subscriber';
import { Subscription } from '../Subscription';
import { tryCatch } from '../util/tryCatch';
import { errorObject } from '../util/errorObject';
import { subscribeToResult } from '../util/subscribeToResult';
import { OuterSubscriber } from '../OuterSubscriber';
import { InnerSubscriber } from '../InnerSubscriber';
@@ -19,7 +17,10 @@ import { ObservableInput, OperatorFunction } from '../types';
*
* ## Example
* Count the number of click events
* ```javascript
* ```ts
* import { fromEvent, of } from 'rxjs';
* import { mapTo, mergeScan } from 'rxjs/operators';
*
* const click$ = fromEvent(document, 'click');
* const one$ = click$.pipe(mapTo(1));
* const seed = 0;
@@ -29,10 +30,10 @@ import { ObservableInput, OperatorFunction } from '../types';
* count$.subscribe(x => console.log(x));
*
* // Results:
* 1
* 2
* 3
* 4
* // 1
* // 2
* // 3
* // 4
* // ...and so on for each click
* ```
*
@@ -45,14 +46,14 @@ import { ObservableInput, OperatorFunction } from '../types';
* @method mergeScan
* @owner Observable
*/
export function mergeScan<T, R>(accumulator: (acc: R, value: T) => ObservableInput<R>,
export function mergeScan<T, R>(accumulator: (acc: R, value: T, index: number) => ObservableInput<R>,
seed: R,
concurrent: number = Number.POSITIVE_INFINITY): OperatorFunction<T, R> {
return (source: Observable<T>) => source.lift(new MergeScanOperator(accumulator, seed, concurrent));
}
export class MergeScanOperator<T, R> implements Operator<T, R> {
constructor(private accumulator: (acc: R, value: T) => ObservableInput<R>,
constructor(private accumulator: (acc: R, value: T, index: number) => ObservableInput<R>,
private seed: R,
private concurrent: number) {
}
@@ -77,7 +78,7 @@ export class MergeScanSubscriber<T, R> extends OuterSubscriber<T, R> {
protected index: number = 0;
constructor(destination: Subscriber<R>,
private accumulator: (acc: R, value: T) => ObservableInput<R>,
private accumulator: (acc: R, value: T, index: number) => ObservableInput<R>,
private acc: R,
private concurrent: number) {
super(destination);
@@ -86,14 +87,16 @@ export class MergeScanSubscriber<T, R> extends OuterSubscriber<T, R> {
protected _next(value: any): void {
if (this.active < this.concurrent) {
const index = this.index++;
const ish = tryCatch(this.accumulator)(this.acc, value);
const destination = this.destination;
if (ish === errorObject) {
destination.error(errorObject.e);
} else {
this.active++;
this._innerSub(ish, value, index);
let ish;
try {
const { accumulator } = this;
ish = accumulator(this.acc, value, index);
} catch (e) {
return destination.error(e);
}
this.active++;
this._innerSub(ish, value, index);
} else {
this.buffer.push(value);
}
+7 -1
View File
@@ -9,7 +9,10 @@ import { MonoTypeOperatorFunction } from '../types';
*
* ## Examples
* Get the minimal value of a series of numbers
* ```javascript
* ```ts
* import { of } from 'rxjs';
* import { min } from 'rxjs/operators';
*
* of(5, 4, 7, 2, 8).pipe(
* min(),
* )
@@ -18,6 +21,9 @@ import { MonoTypeOperatorFunction } from '../types';
*
* Use a comparer function to get the minimal item
* ```typescript
* import { of } from 'rxjs';
* import { min } from 'rxjs/operators';
*
* interface Person {
* age: number,
* name: string
+5 -6
View File
@@ -3,14 +3,13 @@ import { Operator } from '../Operator';
import { Subscriber } from '../Subscriber';
import { Observable } from '../Observable';
import { ConnectableObservable, connectableObservableDescriptor } from '../observable/ConnectableObservable';
import { FactoryOrValue, MonoTypeOperatorFunction, OperatorFunction, UnaryFunction } from '../types';
import { MonoTypeOperatorFunction, OperatorFunction, UnaryFunction, ObservedValueOf, ObservableInput } from '../types';
/* tslint:disable:max-line-length */
export function multicast<T>(subjectOrSubjectFactory: FactoryOrValue<Subject<T>>): UnaryFunction<Observable<T>, ConnectableObservable<T>>;
export function multicast<T>(SubjectFactory: (this: Observable<T>) => Subject<T>): UnaryFunction<Observable<T>, ConnectableObservable<T>>;
export function multicast<T>(SubjectFactory: (this: Observable<T>) => Subject<T>, selector?: MonoTypeOperatorFunction<T>): MonoTypeOperatorFunction<T>;
export function multicast<T, R>(SubjectFactory: (this: Observable<T>) => Subject<T>): UnaryFunction<Observable<T>, ConnectableObservable<R>>;
export function multicast<T, R>(SubjectFactory: (this: Observable<T>) => Subject<T>, selector?: OperatorFunction<T, R>): OperatorFunction<T, R>;
export function multicast<T>(subject: Subject<T>): UnaryFunction<Observable<T>, ConnectableObservable<T>>;
export function multicast<T, O extends ObservableInput<any>>(subject: Subject<T>, selector: (shared: Observable<T>) => O): UnaryFunction<Observable<T>, ConnectableObservable<ObservedValueOf<O>>>;
export function multicast<T>(subjectFactory: (this: Observable<T>) => Subject<T>): UnaryFunction<Observable<T>, ConnectableObservable<T>>;
export function multicast<T, O extends ObservableInput<any>>(SubjectFactory: (this: Observable<T>) => Subject<T>, selector: (shared: Observable<T>) => O): OperatorFunction<T, ObservedValueOf<O>>;
/* tslint:enable:max-line-length */
/**
+4 -1
View File
@@ -33,7 +33,10 @@ import { MonoTypeOperatorFunction, PartialObserver, SchedulerAction, SchedulerLi
*
* ## Example
* Ensure values in subscribe are called just before browser repaint.
* ```javascript
* ```ts
* import { interval } from 'rxjs';
* import { observeOn } from 'rxjs/operators';
*
* const intervals = interval(10); // Intervals are scheduled
* // with async scheduler by default...
* intervals.pipe(
+18 -14
View File
@@ -10,13 +10,15 @@ import { subscribeToResult } from '../util/subscribeToResult';
import { ObservableInput, OperatorFunction } from '../types';
/* tslint:disable:max-line-length */
export function onErrorResumeNext<T, R>(v: ObservableInput<R>): OperatorFunction<T, R>;
export function onErrorResumeNext<T, T2, T3, R>(v2: ObservableInput<T2>, v3: ObservableInput<T3>): OperatorFunction<T, R>;
export function onErrorResumeNext<T, T2, T3, T4, R>(v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>): OperatorFunction<T, R>;
export function onErrorResumeNext<T, T2, T3, T4, T5, R>(v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>): OperatorFunction<T, R>;
export function onErrorResumeNext<T, T2, T3, T4, T5, T6, R>(v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>, v6: ObservableInput<T6>): OperatorFunction<T, R> ;
export function onErrorResumeNext<T, R>(...observables: Array<ObservableInput<any> | ((...values: Array<any>) => R)>): OperatorFunction<T, R>;
export function onErrorResumeNext<T, R>(array: ObservableInput<any>[]): OperatorFunction<T, R>;
export function onErrorResumeNext<T>(): OperatorFunction<T, T>;
export function onErrorResumeNext<T, T2>(v: ObservableInput<T2>): OperatorFunction<T, T | T2>;
export function onErrorResumeNext<T, T2, T3>(v: ObservableInput<T2>, v2: ObservableInput<T3>): OperatorFunction<T, T | T2 | T3>;
export function onErrorResumeNext<T, T2, T3, T4>(v: ObservableInput<T2>, v2: ObservableInput<T3>, v3: ObservableInput<T4>): OperatorFunction<T, T | T2 | T3 | T4>;
export function onErrorResumeNext<T, T2, T3, T4, T5>(v: ObservableInput<T2>, v2: ObservableInput<T3>, v3: ObservableInput<T4>, v4: ObservableInput<T5>): OperatorFunction<T, T | T2 | T3 | T4 | T5>;
export function onErrorResumeNext<T, T2, T3, T4, T5, T6>(v: ObservableInput<T2>, v2: ObservableInput<T3>, v3: ObservableInput<T4>, v4: ObservableInput<T5>, v5: ObservableInput<T6>): OperatorFunction<T, T | T2 | T3 | T4 | T5 | T6>;
export function onErrorResumeNext<T, T2, T3, T4, T5, T6, T7>(v: ObservableInput<T2>, v2: ObservableInput<T3>, v3: ObservableInput<T4>, v4: ObservableInput<T5>, v5: ObservableInput<T6>, v6: ObservableInput<T7>): OperatorFunction<T, T | T2 | T3 | T4 | T5 | T6 | T7>;
export function onErrorResumeNext<T, R>(...observables: Array<ObservableInput<any>>): OperatorFunction<T, T | R>;
export function onErrorResumeNext<T, R>(array: ObservableInput<any>[]): OperatorFunction<T, T | R>;
/* tslint:enable:max-line-length */
/**
@@ -51,11 +53,14 @@ export function onErrorResumeNext<T, R>(array: ObservableInput<any>[]): Operator
*
* ## Example
* Subscribe to the next Observable after map fails
* ```javascript
* ```ts
* import { of } from 'rxjs';
* import { onErrorResumeNext, map } from 'rxjs/operators';
*
* of(1, 2, 3, 0).pipe(
* map(x => {
* if (x === 0) { throw Error(); }
return 10 / x;
* return 10 / x;
* }),
* onErrorResumeNext(of(1, 2, 3)),
* )
@@ -86,8 +91,7 @@ export function onErrorResumeNext<T, R>(array: ObservableInput<any>[]): Operator
*/
export function onErrorResumeNext<T, R>(...nextSources: Array<ObservableInput<any> |
Array<ObservableInput<any>> |
((...values: Array<any>) => R)>): OperatorFunction<T, R> {
Array<ObservableInput<any>>>): OperatorFunction<T, R> {
if (nextSources.length === 1 && isArray(nextSources[0])) {
nextSources = <Array<Observable<any>>>nextSources[0];
}
@@ -107,8 +111,8 @@ export function onErrorResumeNextStatic<R>(array: ObservableInput<any>[]): Obser
/* tslint:enable:max-line-length */
export function onErrorResumeNextStatic<T, R>(...nextSources: Array<ObservableInput<any> |
Array<ObservableInput<any>> |
((...values: Array<any>) => R)>): Observable<R> {
Array<ObservableInput<any>> |
((...values: Array<any>) => R)>): Observable<R> {
let source: ObservableInput<any> = null;
if (nextSources.length === 1 && isArray(nextSources[0])) {
@@ -154,7 +158,7 @@ class OnErrorResumeNextSubscriber<T, R> extends OuterSubscriber<T, R> {
private subscribeToNextSource(): void {
const next = this.nextSources.shift();
if (next) {
if (!!next) {
const innerSubscriber = new InnerSubscriber(this, undefined, undefined);
const destination = this.destination as Subscription;
destination.add(innerSubscriber);
+11 -2
View File
@@ -20,7 +20,10 @@ import { OperatorFunction } from '../types';
*
* ## Example
* On every click (starting from the second), emit the relative distance to the previous click
* ```javascript
* ```ts
* import { fromEvent } from 'rxjs';
* import { pairwise, map } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const pairs = clicks.pipe(pairwise());
* const distance = pairs.pipe(
@@ -67,12 +70,18 @@ class PairwiseSubscriber<T> extends Subscriber<T> {
}
_next(value: T): void {
let pair: [T, T] | undefined;
if (this.hasPrev) {
this.destination.next([this.prev, value]);
pair = [this.prev, value];
} else {
this.hasPrev = true;
}
this.prev = value;
if (pair) {
this.destination.next(pair);
}
}
}
+7 -1
View File
@@ -22,7 +22,10 @@ import { UnaryFunction } from '../types';
*
* ## Example
* Partition click events into those on DIV elements and those elsewhere
* ```javascript
* ```ts
* import { fromEvent } from 'rxjs';
* import { partition } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const parts = clicks.pipe(partition(ev => ev.target.tagName === 'DIV'));
* const clicksOnDivs = parts[0];
@@ -47,6 +50,9 @@ import { UnaryFunction } from '../types';
* @method partition
* @owner Observable
*/
/**
* @deprecated use `partition` static creation function instead
*/
export function partition<T>(predicate: (value: T, index: number) => boolean,
thisArg?: any): UnaryFunction<Observable<T>, [Observable<T>, Observable<T>]> {
return (source: Observable<T>) => [
+14 -1
View File
@@ -2,6 +2,16 @@ import { Observable } from '../Observable';
import { map } from './map';
import { OperatorFunction } from '../types';
/* tslint:disable:max-line-length */
export function pluck<T, K1 extends keyof T>(k1: K1): OperatorFunction<T, T[K1]>;
export function pluck<T, K1 extends keyof T, K2 extends keyof T[K1]>(k1: K1, k2: K2): OperatorFunction<T, T[K1][K2]>;
export function pluck<T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(k1: K1, k2: K2, k3: K3): OperatorFunction<T, T[K1][K2][K3]>;
export function pluck<T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2], K4 extends keyof T[K1][K2][K3]>(k1: K1, k2: K2, k3: K3, k4: K4): OperatorFunction<T, T[K1][K2][K3][K4]>;
export function pluck<T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2], K4 extends keyof T[K1][K2][K3], K5 extends keyof T[K1][K2][K3][K4]>(k1: K1, k2: K2, k3: K3, k4: K4, k5: K5): OperatorFunction<T, T[K1][K2][K3][K4][K5]>;
export function pluck<T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2], K4 extends keyof T[K1][K2][K3], K5 extends keyof T[K1][K2][K3][K4], K6 extends keyof T[K1][K2][K3][K4][K5]>(k1: K1, k2: K2, k3: K3, k4: K4, k5: K5, k6: K6): OperatorFunction<T, T[K1][K2][K3][K4][K5][K6]>;
export function pluck<T, R>(...properties: string[]): OperatorFunction<T, R>;
/* tslint:enable:max-line-length */
/**
* Maps each source value (an object) to its specified nested property.
*
@@ -17,7 +27,10 @@ import { OperatorFunction } from '../types';
*
* ## Example
* Map every click to the tagName of the clicked target element
* ```javascript
* ```ts
* import { fromEvent } from 'rxjs';
* import { pluck } from 'rxjs/operators';
*
* const clicks = fromEvent(document, 'click');
* const tagNames = clicks.pipe(pluck('target', 'tagName'));
* tagNames.subscribe(x => console.log(x));
+39 -2
View File
@@ -2,11 +2,11 @@ import { Observable } from '../Observable';
import { Subject } from '../Subject';
import { multicast } from './multicast';
import { ConnectableObservable } from '../observable/ConnectableObservable';
import { MonoTypeOperatorFunction, OperatorFunction, UnaryFunction } from '../types';
import { MonoTypeOperatorFunction, OperatorFunction, UnaryFunction, ObservableInput, ObservedValueOf } from '../types';
/* tslint:disable:max-line-length */
export function publish<T>(): UnaryFunction<Observable<T>, ConnectableObservable<T>>;
export function publish<T, R>(selector: OperatorFunction<T, R>): OperatorFunction<T, R>;
export function publish<T, O extends ObservableInput<any>>(selector: (shared: Observable<T>) => O): OperatorFunction<T, ObservedValueOf<O>>;
export function publish<T>(selector: MonoTypeOperatorFunction<T>): MonoTypeOperatorFunction<T>;
/* tslint:enable:max-line-length */
@@ -14,14 +14,51 @@ export function publish<T>(selector: MonoTypeOperatorFunction<T>): MonoTypeOpera
* Returns a ConnectableObservable, which is a variety of Observable that waits until its connect method is called
* before it begins emitting items to those Observers that have subscribed to it.
*
* <span class="informal">Makes a cold Observable hot</span>
*
* ![](publish.png)
*
* ## Examples
* Make source$ hot by applying publish operator, then merge each inner observable into a single one
* and subscribe.
* ```ts
* import { of, zip, interval, merge } from "rxjs";
* import { map, publish, tap } from "rxjs/operators";
*
* const source$ = zip(interval(2000), of(1, 2, 3, 4, 5, 6, 7, 8, 9)).pipe(
* map(values => values[1])
* );
*
* source$
* .pipe(
* publish(multicasted$ =>
* merge(
* multicasted$.pipe(tap(x => console.log('Stream 1:', x))),
* multicasted$.pipe(tap(x => console.log('Stream 2:', x))),
* multicasted$.pipe(tap(x => console.log('Stream 3:', x))),
* )
* )
* )
* .subscribe();
*
* // Results every two seconds
* // Stream 1: 1
* // Stream 2: 1
* // Stream 3: 1
* // ...
* // Stream 1: 9
* // Stream 2: 9
* // Stream 3: 9
* ```
*
* @param {Function} [selector] - Optional selector function which can use the multicasted source sequence as many times
* as needed, without causing multiple subscriptions to the source sequence.
* Subscribers to the given source will receive all notifications of the source from the time of the subscription on.
* @return A ConnectableObservable that upon connection causes the source Observable to emit items to its Observers.
* @method publish
* @owner Observable
*
*
*/
export function publish<T, R>(selector?: OperatorFunction<T, R>): MonoTypeOperatorFunction<T> | OperatorFunction<T, R> {
return selector ?
+4 -1
View File
@@ -18,7 +18,10 @@ import { UnaryFunction } from '../types';
*
* ## Example
*
* ```js
* ```ts
* import { interval } from 'rxjs';
* import { publishLast, tap, take } from 'rxjs/operators';
*
* const connectable =
* interval(1000)
* .pipe(
+2 -3
View File
@@ -2,12 +2,11 @@ import { Observable } from '../Observable';
import { ReplaySubject } from '../ReplaySubject';
import { multicast } from './multicast';
import { ConnectableObservable } from '../observable/ConnectableObservable';
import { UnaryFunction, MonoTypeOperatorFunction, OperatorFunction, SchedulerLike } from '../types';
import { UnaryFunction, MonoTypeOperatorFunction, OperatorFunction, SchedulerLike, ObservableInput, ObservedValueOf } from '../types';
/* tslint:disable:max-line-length */
export function publishReplay<T>(bufferSize?: number, windowTime?: number, scheduler?: SchedulerLike): MonoTypeOperatorFunction<T>;
export function publishReplay<T, R>(bufferSize?: number, windowTime?: number, selector?: OperatorFunction<T, R>, scheduler?: SchedulerLike): OperatorFunction<T, R>;
export function publishReplay<T>(bufferSize?: number, windowTime?: number, selector?: MonoTypeOperatorFunction<T>, scheduler?: SchedulerLike): MonoTypeOperatorFunction<T>;
export function publishReplay<T, O extends ObservableInput<any>>(bufferSize?: number, windowTime?: number, selector?: (shared: Observable<T>) => O, scheduler?: SchedulerLike): OperatorFunction<T, ObservedValueOf<O>>;
/* tslint:enable:max-line-length */
export function publishReplay<T, R>(bufferSize?: number,
+5 -5
View File
@@ -15,22 +15,22 @@ export function race<T, R>(...observables: Array<Observable<any> | Array<Observa
/* tslint:enable:max-line-length */
/**
* Returns an Observable that mirrors the first source Observable to emit an item
* from the combination of this Observable and supplied Observables.
* Returns an Observable that mirrors the first source Observable to emit a next,
* error or complete notification from the combination of this Observable and supplied Observables.
* @param {...Observables} ...observables Sources used to race for which Observable emits first.
* @return {Observable} An Observable that mirrors the output of the first Observable to emit an item.
* @method race
* @owner Observable
* @deprecated Deprecated in favor of static {@link race}.
*/
export function race<T>(...observables: Array<Observable<T> | Array<Observable<T>>>): MonoTypeOperatorFunction<T> {
export function race<T>(...observables: (Observable<T> | Observable<T>[])[]): MonoTypeOperatorFunction<T> {
return function raceOperatorFunction(source: Observable<T>) {
// if the only argument is an array, it was most likely called with
// `pair([obs1, obs2, ...])`
if (observables.length === 1 && isArray(observables[0])) {
observables = <Array<Observable<T>>>observables[0];
observables = observables[0] as Observable<T>[];
}
return source.lift.call(raceStatic<T>(source, ...observables));
return source.lift.call(raceStatic(source, ...(observables as Observable<T>[])));
};
}
+11 -8
View File
@@ -6,9 +6,9 @@ import { OperatorFunction, MonoTypeOperatorFunction } from '../types';
import { pipe } from '../util/pipe';
/* tslint:disable:max-line-length */
export function reduce<T, R>(accumulator: (acc: R, value: T, index: number) => R, seed: R): OperatorFunction<T, R>;
export function reduce<T>(accumulator: (acc: T, value: T, index: number) => T, seed?: T): MonoTypeOperatorFunction<T>;
export function reduce<T>(accumulator: (acc: T[], value: T, index: number) => T[], seed: T[]): OperatorFunction<T, T[]>;
export function reduce<T, R>(accumulator: (acc: R, value: T, index: number) => R, seed?: R): OperatorFunction<T, R>;
export function reduce<T, R>(accumulator: (acc: R, value: T, index: number) => R): OperatorFunction<T, R>;
/* tslint:enable:max-line-length */
/**
@@ -36,13 +36,16 @@ export function reduce<T, R>(accumulator: (acc: R, value: T, index: number) => R
*
* ## Example
* Count the number of click events that happened in 5 seconds
* ```javascript
* ```ts
* import { fromEvent, interval } from 'rxjs';
* import { reduce, takeUntil, mapTo } from 'rxjs/operators';
*
* const clicksInFiveSeconds = fromEvent(document, 'click').pipe(
* takeUntil(interval(5000)),
* );
* const ones = clicksInFiveSeconds.pipe(mapTo(1));
* const seed = 0;
* const count = ones.reduce((acc, one) => acc + one, seed);
* const count = ones.pipe(reduce((acc, one) => acc + one, seed));
* count.subscribe(x => console.log(x));
* ```
*
@@ -59,20 +62,20 @@ export function reduce<T, R>(accumulator: (acc: R, value: T, index: number) => R
* @method reduce
* @owner Observable
*/
export function reduce<T, R>(accumulator: (acc: R, value: T, index?: number) => R, seed?: R): OperatorFunction<T, R> {
export function reduce<T, R>(accumulator: (acc: T | R, value: T, index?: number) => T | R, seed?: T | R): OperatorFunction<T, T | R> {
// providing a seed of `undefined` *should* be valid and trigger
// hasSeed! so don't use `seed !== undefined` checks!
// For this reason, we have to check it here at the original call site
// otherwise inside Operator/Subscriber we won't know if `undefined`
// means they didn't provide anything or if they literally provided `undefined`
if (arguments.length >= 2) {
return function reduceOperatorFunctionWithSeed(source: Observable<T>): Observable<R> {
return function reduceOperatorFunctionWithSeed(source: Observable<T>): Observable<T | R> {
return pipe(scan(accumulator, seed), takeLast(1), defaultIfEmpty(seed))(source);
};
}
return function reduceOperatorFunction(source: Observable<T>): Observable<R> {
return function reduceOperatorFunction(source: Observable<T>): Observable<T | R> {
return pipe(
scan((acc: R, value: T, index: number): R => accumulator(acc, value, index + 1)),
scan<T, T | R>((acc, value, index) => accumulator(acc, value, index + 1)),
takeLast(1),
)(source);
};
+53
View File
@@ -5,6 +5,59 @@ import { MonoTypeOperatorFunction, TeardownLogic } from '../types';
import { ConnectableObservable } from '../observable/ConnectableObservable';
import { Observable } from '../Observable';
/**
* Make a {@link ConnectableObservable} behave like a ordinary observable and automates the way
* you can connect to it.
*
* Internally it counts the subscriptions to the observable and subscribes (only once) to the source if
* the number of subscriptions is larger than 0. If the number of subscriptions is smaller than 1, it
* unsubscribes from the source. This way you can make sure that everything before the *published*
* refCount has only a single subscription independently of the number of subscribers to the target
* observable.
*
* Note that using the {@link share} operator is exactly the same as using the *publish* operator
* (making the observable hot) and the *refCount* operator in a sequence.
*
* ![](refCount.png)
*
* ## Example
*
* In the following example there are two intervals turned into connectable observables
* by using the *publish* operator. The first one uses the *refCount* operator, the
* second one does not use it. You will notice that a connectable observable does nothing
* until you call its connect function.
*
* ```ts
* import { interval } from 'rxjs';
* import { tap, publish, refCount } from 'rxjs/operators';
*
* // Turn the interval observable into a ConnectableObservable (hot)
* const refCountInterval = interval(400).pipe(
* tap((num) => console.log(`refCount ${num}`)),
* publish(),
* refCount()
* );
*
* const publishedInterval = interval(400).pipe(
* tap((num) => console.log(`publish ${num}`)),
* publish()
* );
*
* refCountInterval.subscribe();
* refCountInterval.subscribe();
* // 'refCount 0' -----> 'refCount 1' -----> etc
* // All subscriptions will receive the same value and the tap (and
* // every other operator) before the publish operator will be executed
* // only once per event independently of the number of subscriptions.
*
* publishedInterval.subscribe();
* // Nothing happens until you call .connect() on the observable.
* ```
*
* @see {@link ConnectableObservable}
* @see {@link share}
* @see {@link publish}
*/
export function refCount<T>(): MonoTypeOperatorFunction<T> {
return function refCountOperatorFunction(source: ConnectableObservable<T>): Observable<T> {
return source.lift(new RefCountOperator(source));
+47 -3
View File
@@ -5,14 +5,58 @@ import { empty } from '../observable/empty';
import { MonoTypeOperatorFunction, TeardownLogic } from '../types';
/**
* Returns an Observable that repeats the stream of items emitted by the source Observable at most count times.
* Returns an Observable that will resubscribe to the source stream when the source stream completes, at most count times.
*
* <span class="informal">Repeats all values emitted on the source. It's like {@link retry}, but for non error cases.</span>
*
* ![](repeat.png)
*
* Similar to {@link retry}, this operator repeats the stream of items emitted by the source for non error cases.
* Repeat can be useful for creating observables that are meant to have some repeated pattern or rhythm.
*
* Note: `repeat(0)` returns an empty observable and `repeat()` will repeat forever
*
* ## Example
* Repeat a message stream
* ```ts
* import { of } from 'rxjs';
* import { repeat, delay } from 'rxjs/operators';
*
* const source = of('Repeat message');
* const example = source.pipe(repeat(3));
* example.subscribe(x => console.log(x));
*
* // Results
* // Repeat message
* // Repeat message
* // Repeat message
* ```
*
* Repeat 3 values, 2 times
* ```ts
* import { interval } from 'rxjs';
* import { repeat, take } from 'rxjs/operators';
*
* const source = interval(1000);
* const example = source.pipe(take(3), repeat(2));
* example.subscribe(x => console.log(x));
*
* // Results every second
* // 0
* // 1
* // 2
* // 0
* // 1
* // 2
* ```
*
* @see {@link repeatWhen}
* @see {@link retry}
*
* @param {number} [count] The number of times the source Observable items are repeated, a count of 0 will yield
* an empty Observable.
* @return {Observable} An Observable that repeats the stream of items emitted by the source Observable at most
* count times.
* @return {Observable} An Observable that will resubscribe to the source stream when the source stream completes
* , at most count times.
* @method repeat
* @owner Observable
*/
+21 -4
View File
@@ -3,8 +3,6 @@ import { Subscriber } from '../Subscriber';
import { Observable } from '../Observable';
import { Subject } from '../Subject';
import { Subscription } from '../Subscription';
import { tryCatch } from '../util/tryCatch';
import { errorObject } from '../util/errorObject';
import { OuterSubscriber } from '../OuterSubscriber';
import { InnerSubscriber } from '../InnerSubscriber';
@@ -20,6 +18,22 @@ import { MonoTypeOperatorFunction, TeardownLogic } from '../types';
*
* ![](repeatWhen.png)
*
* ## Example
* Repeat a message stream on click
* ```ts
* import { of, fromEvent } from 'rxjs';
* import { repeatWhen } from 'rxjs/operators';
*
* const source = of('Repeat message');
* const documentClick$ = fromEvent(document, 'click');
*
* source.pipe(repeatWhen(() => documentClick$)
* ).subscribe(data => console.log(data))
* ```
* @see {@link repeat}
* @see {@link retry}
* @see {@link retryWhen}
*
* @param {function(notifications: Observable): Observable} notifier - Receives an Observable of notifications with
* which a user can `complete` or `error`, aborting the repetition.
* @return {Observable} The source Observable modified with repeat logic.
@@ -113,8 +127,11 @@ class RepeatWhenSubscriber<T, R> extends OuterSubscriber<T, R> {
private subscribeToRetries() {
this.notifications = new Subject();
const retries = tryCatch(this.notifier)(this.notifications);
if (retries === errorObject) {
let retries;
try {
const { notifier } = this;
retries = notifier(this.notifications);
} catch (e) {
return super.complete();
}
this.retries = retries;

Some files were not shown because too many files have changed in this diff Show More