简单模拟实现Rxjs Observable

1.先定义类型

export type Observer = {
    next: (any) => void,
    complete?: (any) => void,
}

export interface OnSubscribeAction {
    (observer: Observer): void;
}

 export interface mapFun {
      (x: any): any
  }
 

2.自定义类

export class MyObservable {
    private subscribeAction: OnSubscribeAction;
    constructor(subscribeAction: OnSubscribeAction) {
        this.subscribeAction = subscribeAction;
    }

    subscribe(observer: Observer) {
        return this.subscribeAction(observer)
    }
}

3.实例

const onSubscribe: OnSubscribeAction = (observer: Observer) => {
      observer.next(1);
      observer.next(2);
      observer.next(3);
}

const theObserver = {
   next: console.log,
}

const source$ =  new MyObservable(onSubscribe);
source$.subscribe(theObserver);

结果一次输出1,2,3

 

4.增加map操作符

export class MyObservable {
    private subscribeAction: OnSubscribeAction;
    constructor(subscribeAction: OnSubscribeAction) {
        this.subscribeAction = subscribeAction;
    }

    subscribe(observer: Observer) {
        return this.subscribeAction(observer)
    }
  //rxjs 的每个操作符都会返回一个新的Observable
    map(fun: mapFun) {
         const nextObserver =  new MyObservable((observer: Observer) => {
            this.subscribe({
                next(item){
                    observer.next(fun(item))
                }
            })
         })
         return nextObserver
    }
}

5.再次调用

const onSubscribe: OnSubscribeAction = (observer: Observer) => {
      observer.next(1);
      observer.next(2);
      observer.next(3);
    }

    const theObserver = {
      next: console.log,
    }

    const source$ =  MyObservable.create(onSubscribe);
    source$.map(x => x * 2).map(x => x + 1).subscribe(theObserver);

结果一次输出3,5,7

 

=====================================

更进一步把map作为一个单独的函数抽离

export function map(fun: mapFun) {
    const nextObserver =  new MyObserver((observer: Observer) => {
       this.subscribe({
           next(item){
               observer.next(fun(item))
           }
       })
    })
    return nextObserver
}

完整代码如下所示

export type Observer = {
    next: (any) => void,
    complete?: (any) => void,
}

export interface OnSubscribeAction {
    (observer: Observer): void;
}

export interface mapFun {
    (x: any): any
}


export function map(fun: mapFun) {
    const nextObserver =  new MyObservable((observer: Observer) => {
       this.subscribe({
           next(item){
               observer.next(fun(item))
           }
       })
    })
    return nextObserver
}

export class MyObservable {
    private subscribeAction: OnSubscribeAction;
    constructor(subscribeAction: OnSubscribeAction) {
        this.subscribeAction = subscribeAction;
    }

    static create(subscribeAction: OnSubscribeAction) {
        return new MyObservable(subscribeAction)
    }

    subscribe(observer: Observer) {
        return this.subscribeAction(observer)
    }
}

由于map函数中使用到this,需要用call或者apply或者bind改变其指向,使用示例如下

 const onSubscribe: OnSubscribeAction = (observer: Observer) => {
      observer.next(1);
      observer.next(2);
      observer.next(3);
    }

    const theObserver = {
      next: console.log,
    }

    const source$ =  new MyObservable(onSubscribe);
    const subScribtion$ = map.call(source$, x => x * 2);
    map.call(subScribtion$, x => x + 1).subscribe(theObserver);

输出结果依次为3,5,7

 

=====================

由于在map函数中需要访问this, 导致map不是一个纯函数。在map中的this指代上一个observable,现在改为通过参数传递的形式把上一个observable传递给下一个observable。

map函数修改如下

export function map(fun: mapFun) {
    return function(obs$) {
        const nextObserver =  new MyObservable((observer: Observer) => {
            obs$.subscribe({
                next(item){
                    observer.next(fun(item))
                }
            })
         })
         return nextObserver
    }
}

同时MyObservable自定义类需要增加一个pipe方法

export class MyObservable {
    private subscribeAction: OnSubscribeAction;
    constructor(subscribeAction: OnSubscribeAction) {
        this.subscribeAction = subscribeAction;
    }

    subscribe(observer: Observer) {
        return this.subscribeAction(observer)
    } 

    pipe(fn: any){
        return fn(this);
    }
}

最终的调用方式如下

const onSubscribe: OnSubscribeAction = (observer: Observer) => {
      observer.next(1);
      observer.next(2);
      observer.next(3);
    }

    const theObserver = {
      next: console.log,
    }

    const source$ =  new MyObservable(onSubscribe);
    source$.pipe(map(x => x*2)).pipe(map(x => x + 1)).subscribe(theObserver)

结果依次输出3,5,7

 

posted @ 2020-05-04 18:57  痴货  阅读(349)  评论(0编辑  收藏  举报