1+ import Observable from '../Observable' ;
2+ import Operator from '../Operator' ;
3+ import Subscriber from '../Subscriber' ;
4+ import Observer from '../Observer' ;
5+
6+ import tryCatch from '../util/tryCatch' ;
7+ import { errorObject } from '../util/errorObject' ;
8+ import bindCallback from '../util/bindCallback' ;
9+ import EmptyError from '../util/EmptyError' ;
10+
11+ export default function last < T > ( predicate ?: ( value : T , index : number , source :Observable < T > ) => boolean , thisArg ?: any , defaultValue ?: any ) : Observable < T > {
12+ return this . lift ( new LastOperator ( predicate , thisArg , defaultValue , this ) ) ;
13+ }
14+
15+ class LastOperator < T , R > implements Operator < T , R > {
16+ constructor ( private predicate ?: ( value : T , index : number , source :Observable < T > ) => boolean , private thisArg ?: any , private defaultValue ?: any , private source ?: Observable < T > ) {
17+
18+ }
19+
20+ call ( observer : Subscriber < R > ) : Subscriber < T > {
21+ return new LastSubscriber ( observer , this . predicate , this . thisArg , this . defaultValue , this . source ) ;
22+ }
23+ }
24+
25+ class LastSubscriber < T > extends Subscriber < T > {
26+ private lastValue : T ;
27+ private hasValue : boolean = false ;
28+ private predicate : Function ;
29+ private index : number = 0 ;
30+
31+ constructor ( destination : Observer < T > , predicate ?: ( value : T , index : number , source : Observable < T > ) => boolean ,
32+ private thisArg ?: any , private defaultValue ?: any , private source ?: Observable < T > ) {
33+ super ( destination ) ;
34+ if ( typeof defaultValue !== 'undefined' ) {
35+ this . lastValue = defaultValue ;
36+ this . hasValue = true ;
37+ }
38+ if ( typeof predicate === 'function' ) {
39+ this . predicate = bindCallback ( predicate , thisArg , 3 ) ;
40+ }
41+ }
42+
43+ _next ( value : T ) {
44+ const predicate = this . predicate ;
45+ if ( predicate ) {
46+ let result = tryCatch ( predicate ) ( value , this . index ++ , this . source ) ;
47+ if ( result === errorObject ) {
48+ this . destination . error ( result . e ) ;
49+ } else if ( result ) {
50+ this . lastValue = result ;
51+ this . hasValue = true ;
52+ }
53+ } else {
54+ this . lastValue = value ;
55+ this . hasValue = true ;
56+ }
57+ }
58+
59+ _complete ( ) {
60+ const destination = this . destination ;
61+ if ( this . hasValue ) {
62+ destination . next ( this . lastValue ) ;
63+ destination . complete ( ) ;
64+ } else {
65+ destination . error ( new EmptyError ) ;
66+ }
67+ }
68+ }
0 commit comments