es6/operator/last.js
import { Subscriber } from '../Subscriber';
import { EmptyError } from '../util/EmptyError';
/* tslint:enable:max-line-length */
/**
* 返回的 Observable 只发出由源 Observable 发出的最后一个值。它可以接收一个可选的 predicate 函数作为
* 参数,如果传入 predicate 的话则发送的不是源 Observable 的最后一项,而是发出源 Observable 中
* 满足 predicate 函数的最后一项。
*
* <img src="./img/last.png" width="100%">
*
* @throws {EmptyError} 如果 Observale 完成前还没有发出任何 `next` 通知的话,就会
* 发送 EmptyError 给观察者的 `error` 回调函数。
* @param {function} predicate - 任何由源 Observable 发出的项都必须满足的条件函数。
* @return {Observable} 该 Observable 只发出源 Observable 中满足给定条件的最后一项,
* 或者没有任何项满足条件时发出 NoSuchElementException 。
* @throws - 如果在源 Observable 中没有匹配 predicate 函数的项,则抛出。
* @method last
* @owner Observable
*/
export function last(predicate, resultSelector, defaultValue) {
return this.lift(new LastOperator(predicate, resultSelector, defaultValue, this));
}
class LastOperator {
constructor(predicate, resultSelector, defaultValue, source) {
this.predicate = predicate;
this.resultSelector = resultSelector;
this.defaultValue = defaultValue;
this.source = source;
}
call(observer, source) {
return source.subscribe(new LastSubscriber(observer, this.predicate, this.resultSelector, this.defaultValue, this.source));
}
}
/**
* We need this JSDoc comment for affecting ESDoc.
* @ignore
* @extends {Ignored}
*/
class LastSubscriber extends Subscriber {
constructor(destination, predicate, resultSelector, defaultValue, source) {
super(destination);
this.predicate = predicate;
this.resultSelector = resultSelector;
this.defaultValue = defaultValue;
this.source = source;
this.hasValue = false;
this.index = 0;
if (typeof defaultValue !== 'undefined') {
this.lastValue = defaultValue;
this.hasValue = true;
}
}
_next(value) {
const index = this.index++;
if (this.predicate) {
this._tryPredicate(value, index);
}
else {
if (this.resultSelector) {
this._tryResultSelector(value, index);
return;
}
this.lastValue = value;
this.hasValue = true;
}
}
_tryPredicate(value, index) {
let result;
try {
result = this.predicate(value, index, this.source);
}
catch (err) {
this.destination.error(err);
return;
}
if (result) {
if (this.resultSelector) {
this._tryResultSelector(value, index);
return;
}
this.lastValue = value;
this.hasValue = true;
}
}
_tryResultSelector(value, index) {
let result;
try {
result = this.resultSelector(value, index);
}
catch (err) {
this.destination.error(err);
return;
}
this.lastValue = result;
this.hasValue = true;
}
_complete() {
const destination = this.destination;
if (this.hasValue) {
destination.next(this.lastValue);
destination.complete();
}
else {
destination.error(new EmptyError);
}
}
}
//# sourceMappingURL=last.js.map