[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 ...
随机推荐
- STM32 F4 DAC DMA Waveform Generator
STM32 F4 DAC DMA Waveform Generator Goal: generating an arbitrary periodic waveform using a DAC with ...
- IAR EWARM Checksum Technical Note
IELFTOOL Checksum - Basic actions EW targets: ARM, RH850, RX, SH, STM8 EW component: General issues ...
- Java深入 - 深入 Java自己定义注解
我们在使用Spring框架的时候,会常常使用类似:@Autowired 这种注解. 我们也能够自定义一些注解.Java的注解主要在包:java.lang.annotation中实现. 1. 元注解 什 ...
- delphi dxRibbon中 F10快捷键不好用的原因
最近在项目中使用ribbon ,用F10做快捷键,但是不好用, 不好用的原因是dxBarManager1 中的有个选项UseF10ForMenu, 把这项关闭就可以了
- 移植Python2到TQ2440
环境 Python:2.7.13 开发板: TQ2440 工具链: arm-none-linux-gnueabi-gcc 4.8.3 概述 前面已经把Python3移植到TQ2440上面的,现在我们移 ...
- 在ASP.NET MVC实现购物车,尝试一种不同于平常的购物车显示方式
通常,我们看到的购物车是这样的: 虽然这种购物车显示方式被广泛运用,但我个人觉得不够直观.如果换成这样呢? 本篇的源码放在了:https://github.com/darrenji/ShoppingC ...
- value stored to value2 during its initialization is never read
警告:value stored to value2 during its initialization is never read NSMutableArray *datesArray = [[NSM ...
- 【转】iPhone易被窃听应用三分钟即可获取所有信息
2011年8月9日10:19 “你有iPhone吗?这下你麻烦了!”昨天香港<东方日报>封面文章用这样的语气报道说,一种iPhone等智能手机窃听程序,正引爆香港. 该报记者亲自试验,发现 ...
- Git:常用命令(二)
查看提交历史 git log 撤消操作 任何时候,你都有可能需要撤消刚才所做的某些操作.接下来,我们会介绍一些基本的撤消操作相关的命令.请注意,有些操作并不总是可以撤消的,所以请务必谨慎小心,一旦失误 ...
- 多个类定义attr属性重复的问题:Attribute "xxx" has already been defined
有时候做自定义控件时就会遇到命名冲突,改变有冲突的名字自然是最直接有效的方式,但是感觉很傻.我搜了下别人的解决方案,觉得很值得借鉴.就是把重名的属性,独立出来写一下,然后在定义时直接写属性名字即可. ...