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([, , , ])
.pipe(map(x => x * ))
.pipe(filter(x => x < ))
.subscribe(val => console.log(val));
// 2
//

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) {
[, , , ].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) {
[, , , ].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 * ))
.pipe(map(x => x - ))
.subscribe(observer); clickObservable
.pipe(map(ev => [ev.clientX, ev.clientY]))
.pipe(filter(([x, y]) => x < && y < ))
.subscribe(observer);

[RxJS] Build your own RxJS的更多相关文章

  1. RxJS入门2之Rxjs的安装

    RxJS V6.0+ 安装 RxJS 的 import 路径有以下 5 种: 1.创建 Observable 的方法.types.schedulers 和一些工具方法 import { Observa ...

  2. [rxjs] Throttled Buffering in RxJS (debounce)

    Capturing every event can get chatty. Batching events with a throttled buffer in RxJS lets you captu ...

  3. [RxJS] Stream Processing With RxJS vs Array Higher-Order Functions

    Higher order Array functions such as filter, map and reduce are great for functional programming, bu ...

  4. [RxJS] Combining streams in RxJS

    Source: Link We will looking some opreators for combining stream in RxJS: merge combineLatest withLa ...

  5. [RxJS] Error Handling in RxJS

    Get your code back on the happy path! This lesson covers a variety of ways to handle exceptions thro ...

  6. [RxJS 6] The Retry RxJs Error Handling Strategy

    When we want to handle error observable in RxJS v6+, we can use 'retryWhen' and 'delayWhen': const c ...

  7. rxjs入门4之rxjs模式设计

    观察者模式 (Observer Pattern) 观察者模式其实在日常编码中经常遇到,比如DOM的事件监听,代码如下 function clickHandler(event) { console.lo ...

  8. angular2 学习笔记 ( Rxjs, Promise, Async/Await 的区别 )

    Promise 是 ES 6 Async/Await 是 ES 7 Rxjs 是一个 js 库 在使用 angular 时,你会经常看见这 3 个东西. 它们都和异步编程有关,有些情况下你会觉得用它们 ...

  9. [转]VS Code 扩展 Angular 6 Snippets - TypeScript, Html, Angular Material, ngRx, RxJS & Flex Layout

    本文转自:https://marketplace.visualstudio.com/items?itemName=Mikael.Angular-BeastCode VSCode Angular Typ ...

随机推荐

  1. 微信小程序如何玩转分销

    截止目前,微信月活跃用户已经高达8.89亿,微信这个庞大的互联网巨头下一个目标是什么? 打造属于自己的“AppStore”.小程序正是完成这个微信生态体系的一块完美拼板, 张小龙预言:未来2年内,小程 ...

  2. rcp(插件开发)插件B需要引用插件A中的jar包-如何处理依赖关系

    如果插件B需要引用插件A中的jar 通常需要以下几步: 1.插件B要依赖插件A 2.在插件B的build path中添加插件A的jar包 3.插件A的runtime导出插件B中使用jar的packag ...

  3. VC设置代理方法

      参考文章: VC 设置代理 Setting and Retrieving Internet Options Change Internet Proxy settings http://suppor ...

  4. Direct3d 设备丢失 (device lost) (转载)

    转:http://blog.csdn.net/kuangfengwu/article/details/7674074 1.什么时候设备丢失 一个Direct3D设备, 有两种状态: 操作状态或丢失状态 ...

  5. c#开发activex注册问题

    最近使用c#开发activex,遇到一个问题,生成的dll文件在本地可以嵌入到web里面,但是到其他机器上就会出现activex无法加载的情况,页面里面出现一个红色的X.mfc开发的activex是使 ...

  6. Delphi 局域网点对点文件传输(IdTcpClient控件)

    unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...

  7. sql语句中having的作用是?

    HAVING对由sum或其它集合函数运算结果的输出进行限制.比如,我们可能只希望看到Store_Information数据表中销售总额超过1500美圆的商店的信息,这时我们就需要使用HAVING从句. ...

  8. 在CentOS4上安装JMagick

    用Java做网站经常要处理用户上传的图片,例如生成缩略图等等.虽然Java可以使用Java2D进行一些图片操作,但是功能和效率实在太差了. 目前比较好的是用JMagick来进行图像处理,不过JMagi ...

  9. Iphone控件大全

    Iphone的常用控件有哪些?看看下面 一 视图UIView和UIWindow iphone视图的规则是:一个窗口,多个视图.UIWindow相当于电视机,UIViews相当于演员. 1.显示数据的视 ...

  10. 图标框架Font Awesome

    直接引入Font Awesome的css <!DOCTYPE html> <html lang="en"> <head> <meta ch ...