[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([, , , ])
.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的更多相关文章
- RxJS入门2之Rxjs的安装
RxJS V6.0+ 安装 RxJS 的 import 路径有以下 5 种: 1.创建 Observable 的方法.types.schedulers 和一些工具方法 import { Observa ...
- [rxjs] Throttled Buffering in RxJS (debounce)
Capturing every event can get chatty. Batching events with a throttled buffer in RxJS lets you captu ...
- [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 ...
- [RxJS] Combining streams in RxJS
Source: Link We will looking some opreators for combining stream in RxJS: merge combineLatest withLa ...
- [RxJS] Error Handling in RxJS
Get your code back on the happy path! This lesson covers a variety of ways to handle exceptions thro ...
- [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 ...
- rxjs入门4之rxjs模式设计
观察者模式 (Observer Pattern) 观察者模式其实在日常编码中经常遇到,比如DOM的事件监听,代码如下 function clickHandler(event) { console.lo ...
- angular2 学习笔记 ( Rxjs, Promise, Async/Await 的区别 )
Promise 是 ES 6 Async/Await 是 ES 7 Rxjs 是一个 js 库 在使用 angular 时,你会经常看见这 3 个东西. 它们都和异步编程有关,有些情况下你会觉得用它们 ...
- [转]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 ...
随机推荐
- CSDN博客的积分计算方法和博客排名规律
开通博客一段时间了,近期莫名其妙得获得"持之以恒"的勋章,看着日益增长的积分,既兴奋又好奇.本人对CSDN博客积分的计算方法非常疑惑,也不知当中怎么回事,好奇度娘一番,并结合CSD ...
- 《大话设计模式》C#/C++版pdf/源码下载
大话设计模式(带目录完整版)[中文PDF+源代码].zip 下载地址:http://pan.baidu.com/s/1giQP4大话设计模式C++.pdf下载地址:http://pan.baidu.c ...
- Task.FromResult应用场景举例
Task.FromResult用来创建一个带返回值的.已完成的Task. 场景一:以同步的方式实现一个异步接口方法 比如有一个接口包含异步方法. interface IMyInterface { Ta ...
- 奇怪的问题,疑惑?不用的 User agent 居然gzip不一样?
问题描述: 使用同一款浏览器(Chrome Version 41.0.2272.118 (64-bit)),访问同一个地址:http://www.skhktown.com/hkcity/resourc ...
- IOS开发常用宏定义
//release屏蔽NSLog//放在.pch文件里#ifdef DEBUG #else#define NSLog(...) {};#endif //G.C.D#define BACK(block) ...
- C#高级编程小结
小结 这几章主要介绍了如何使用新的dynamic类型,还讨论了编译器在遇到dynamic类型时会做什么.还讨论了DLP,可以把它包含在简单的应用程序中.并通过Pythin使用DLR,执行Python脚 ...
- 无耻之徒(美版)第七季/全集Shameless US迅雷下载
英文全名Shameless (US),第7季(2016).本季看点:<无耻之徒>(Shameless)第七季.本季故事起始于「一个月之后」,Frank从昏迷中醒来后得知亲人背叛了他,于是向 ...
- 在MFC内竟然不可以解析“Mat”
调试了好久,在MFC内竟然不可以解析“Mat” 总是显示"Mat"没有定义,改动include.lib.依赖库, 不断地改动: #include "opencv2/img ...
- ListView取消和自定义分割线的方法
一.不显示分割线 XML android:footerDividersEnabled="false"即可. JAVA mListView.setDivider(null); 二.改 ...
- [转]PHP中替换换行符
FROM :http://www.cnblogs.com/siqi/archive/2012/10/12/2720713.html //php 有三种方法来解决 //1.使用str_replace 来 ...