es6/operator/onErrorResumeNext.js
import { FromObservable } from '../observable/FromObservable';
import { isArray } from '../util/isArray';
import { OuterSubscriber } from '../OuterSubscriber';
import { subscribeToResult } from '../util/subscribeToResult';
/* tslint:enable:max-line-length */
/**
* 当任何提供的 Observable 发出完成或错误通知时,它会立即地订阅已传入下一个 Observable 。
*
* <span class="informal">无论发生什么,都会执行一系列的 Observables ,即使这意味着要吞咽错误。</span>
*
* <img src="./img/onErrorResumeNext.png" width="100%">
*
* `onErrorResumeNext` 操作符接收一系列的 Observables ,可与直接作为参数或数组提供。如果没提供 Observable ,
* 返回的 Observable 与源 Observable 的行为是相同的。
*
* `onErrorResumeNext` 返回的 Observable 通过订阅和重新发出源 Observable 的值开始。当流的值完成时,无论 Observable
* 是完成还是发出错误,`onErrorResumeNext` 都会订阅作为参数传给该方法的第一个 Observable 。它也会开始重新发出它的值,
* 再一次,当流完成时,`onErrorResumeNext` 又会继续订阅已提供的系列 Observable 中另一个,无论前一个 Observable
* 是否完成或发生错误。这样的行为会持续到系列中没有更多的 Observable ,返回的 Observale 将在此时完成,即使最后订阅的
* 流是以错误结束的。
*
* 因此, `onErrorResumeNext` 可以认为是某个版本的 {@link concat} 操作符,只是当它的输入 Observables 发生
* 错误时,它更为宽容。然而,`concat` 只有当前一个 Observable 成功完成了,它才会订阅系列中的下个 Observable ,
* 而 `onErrorResumeNext` 即使是以错误完成某个 Observalbe 时,它也会订阅下一个。
*
* 注意,对于由 Observables 发出的错误,你无法获得访问权限。特别是不要指望可以将这些出现在错误回调函数中的
* 错误传递给 {@link subscribe} 。如果要根据 Observable 发出的错误采取特定的操作,应该尝试使用 {@link catch} 。
*
*
* @example <caption>在 map 操作失败后订阅下一个 Observable </caption>
* Rx.Observable.of(1, 2, 3, 0)
* .map(x => {
* if (x === 0) { throw Error(); }
return 10 / x;
* })
* .onErrorResumeNext(Rx.Observable.of(1, 2, 3))
* .subscribe(
* val => console.log(val),
* err => console.log(err), // 永远不会调用
* () => console.log('that\'s it!')
* );
*
* // 输出:
* // 10
* // 5
* // 3.3333333333333335
* // 1
* // 2
* // 3
* // "that's it!"
*
* @see {@link concat}
* @see {@link catch}
*
* @param {...ObservableInput} observables 传入的 Observables,可以直接传入,也可以作为数组传入。
* @return {Observable} 该 Observable 发出源 Observable 的值,但如果发出错误,它会订阅下一个传入的
* Observable ,并以此类推,直到它完成或用完所有的 Observable 。
* @method onErrorResumeNext
* @owner Observable
*/
export function onErrorResumeNext(...nextSources) {
if (nextSources.length === 1 && isArray(nextSources[0])) {
nextSources = nextSources[0];
}
return this.lift(new OnErrorResumeNextOperator(nextSources));
}
/* tslint:enable:max-line-length */
export function onErrorResumeNextStatic(...nextSources) {
let source = null;
if (nextSources.length === 1 && isArray(nextSources[0])) {
nextSources = nextSources[0];
}
source = nextSources.shift();
return new FromObservable(source, null).lift(new OnErrorResumeNextOperator(nextSources));
}
class OnErrorResumeNextOperator {
constructor(nextSources) {
this.nextSources = nextSources;
}
call(subscriber, source) {
return source.subscribe(new OnErrorResumeNextSubscriber(subscriber, this.nextSources));
}
}
class OnErrorResumeNextSubscriber extends OuterSubscriber {
constructor(destination, nextSources) {
super(destination);
this.destination = destination;
this.nextSources = nextSources;
}
notifyError(error, innerSub) {
this.subscribeToNextSource();
}
notifyComplete(innerSub) {
this.subscribeToNextSource();
}
_error(err) {
this.subscribeToNextSource();
}
_complete() {
this.subscribeToNextSource();
}
subscribeToNextSource() {
const next = this.nextSources.shift();
if (next) {
this.add(subscribeToResult(this, next));
}
else {
this.destination.complete();
}
}
}
//# sourceMappingURL=onErrorResumeNext.js.map