博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[RxJS] Build your own RxJS
阅读量:4641 次
发布时间:2019-06-09

本文共 4253 字,大约阅读时间需要 14 分钟。

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);

 

转载于:https://www.cnblogs.com/Answer1215/p/10662844.html

你可能感兴趣的文章
儿子和女儿——解释器和编译器的区别与联系
查看>>
第一阶段冲刺3
查看>>
父类引用指向子类对象
查看>>
网页如何实现下载功能
查看>>
IT男专用表白程序
查看>>
读《大道至简》第六章感想
查看>>
ef linq 中判断实体中是否包含某集合
查看>>
章三 链表
查看>>
Solution for Concurrent number of AOS' for this application exceeds the licensed number
查看>>
CSE 3100 Systems Programming
查看>>
IntelliJ IDEA 的Project structure说明
查看>>
Java Security(JCE基本概念)
查看>>
Linux Supervisor的安装与使用入门
查看>>
创建 PSO
查看>>
JasperReport报表设计4
查看>>
项目活动定义 概述
查看>>
团队冲刺04
查看>>
我的Python分析成长之路8
查看>>
泛型在三层中的应用
查看>>
SharePoint2010 -- 管理配置文件同步
查看>>