zoukankan      html  css  js  c++  java
  • [RxJS] Build your own RxJS

    JavaScript has multiple APIs that use callback functions that all do nearly the same thing with slight variations. Event listeners, array methods such as .forEach, promises, and NodeJS streams all are very close in the way they are written. Instead, in RxJS you'd unify all of these APIs under one abstraction.

    Normal RxJS API:

    import { from } from "rxjs";
    import { map, filter } from "rxjs/operators";
    
    from([1, 2, 3, 4])
      .pipe(map(x => x * 2))
      .pipe(filter(x => x < 5))
      .subscribe(val => console.log(val)); 
    // 2 
    // 4

    We can build our own RxJS operator

    First, Observable,

      it has API:

    {
      subscribe() {}
      pipe() {}  
    }

    We can create a function call 'createObservable(subscribe)', take a subscribe function, return a subscribe and pipe function:

    function createObservable(subscribe) {
      return {
        subscribe,
        pipe(operator) {
          return operator(this);
        }
      };
    }

    We can use it to create Observables:

    const numberObservable = createObservable(function(observer) {
      [10, 20, 30, 40].forEach(x => {
        observer.next(x);
      });
    
      observer.complete();
    });
    
    const clickObservable = createObservable(function(observer) {
      document.addEventListener("click", function(ev) {
        observer.next(ev);
      });
    });

    Second, Observer: 

      Observer is easy, it takes a object which contains 'next', 'error', 'complete' functions:

    const observer = {
      next(x) {
        console.log(x);
      },
      error(err) {
        console.error(err);
      },
      complete() {
        console.log("DONE");
      }
    };

    Third, Operator, map, filter:

    map(fn)(observable)

    filter(predFn)(observable)  

    It is important to know that map & filter, those operator, takes an inputObservable and will return an outputObservable.

    We subscribe inputObservable, and inputObserver, inside inputObserver, we call outputObserver which is passed in from the consumer.

    const map = fn => inputObservable => {
      const outputObservable = createObservable(function(outputObserver) {
        const observer = {
          next(x) {
            const res = fn(x);
            outputObserver.next(res);
          },
          error(err) {
            outputObserver.error(err);
          },
          complete() {
            outputObserver.complete();
          }
        };
        inputObservable.subscribe(observer);
      });
    
      return outputObservable;
    };
    
    const filter = fn => inputObservable => {
      const outputObservable = createObservable(function(outputObserver) {
        const observer = {
          next(x) {
            if (fn(x)) {
              outputObserver.next(x);
            }
          },
          error(err) {
            outputObserver.error(err);
          },
          complete() {
            outputObserver.complete();
          }
        };
        inputObservable.subscribe(observer);
      });
    
      return outputObservable;
    };

    --

    Full Code:

    function createObservable(subscribe) {
      return {
        subscribe,
        pipe(operator) {
          return operator(this);
        }
      };
    }
    
    const numberObservable = createObservable(function(observer) {
      [10, 20, 30, 40].forEach(x => {
        observer.next(x);
      });
    
      observer.complete();
    });
    
    const clickObservable = createObservable(function(observer) {
      document.addEventListener("click", function(ev) {
        observer.next(ev);
      });
    });
    
    const map = fn => inputObservable => {
      const outputObservable = createObservable(function(outputObserver) {
        const observer = {
          next(x) {
            const res = fn(x);
            outputObserver.next(res);
          },
          error(err) {
            outputObserver.error(err);
          },
          complete() {
            outputObserver.complete();
          }
        };
        inputObservable.subscribe(observer);
      });
    
      return outputObservable;
    };
    
    const filter = fn => inputObservable => {
      const outputObservable = createObservable(function(outputObserver) {
        const observer = {
          next(x) {
            if (fn(x)) {
              outputObserver.next(x);
            }
          },
          error(err) {
            outputObserver.error(err);
          },
          complete() {
            outputObserver.complete();
          }
        };
        inputObservable.subscribe(observer);
      });
    
      return outputObservable;
    };
    
    const observer = {
      next(x) {
        console.log(x);
      },
      error(err) {
        console.error(err);
      },
      complete() {
        console.log("DONE");
      }
    };
    
    numberObservable
      .pipe(map(x => x * 3))
      .pipe(map(x => x - 9))
      .subscribe(observer);
    
    clickObservable
      .pipe(map(ev => [ev.clientX, ev.clientY]))
      .pipe(filter(([x, y]) => x < 200 && y < 200))
      .subscribe(observer);
  • 相关阅读:
    15.mysql数据库操作与Paramiko模块
    14.Gevent协程 SelectPollEpoll异步IO与事件驱动 Python连接Mysql数据库操作 RabbitMQ队列 RedisMemcached缓存 Paramiko SSH Twsited网络框架
    13 线程threading模块 join 线程锁之LockRlock信号量 将线程变为守护进程 Event事件  queue队列 生产者消费者模型 Queue队列 开发一个线程池 进程 语法 进程间通讯 进程池  多进程multiprocessing
    12.异常 isinstance 反射
    2.semantic-ui的官网文档说明
    11.Socket网络编程
    10.面向对象高级语法部分 经典类vs新式类   静态方法、类方法、属性方法 类的特殊方法 反射 异常处理 Socket开发基础
    9.对象 面向对象的特性:封装、继承、多态 类、方法、 #数据描述
    8.模块介绍 time &datetime模块 random os sys shutil json & picle shelve xml处理 yaml处理 configparser hashlib subprocess logging模块 re正则表达式
    1.sematic ui 安装
  • 原文地址:https://www.cnblogs.com/Answer1215/p/10662844.html
Copyright © 2011-2022 走看看