[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 ...
随机推荐
- Programmed Adjustable Power
Programmed Adjustable Power I just explored an easy scheme to design a high precision programmed adj ...
- PHP 如何创建守护(daemon)进程
先讲几个概念 守护进程: Linux中的后台服务进程.它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程常常在系统引导装入时启动,在系统关闭时终止. ...
- 对一个前端使用AngularJS后端使用ASP.NET Web API项目的理解(1)
chsakell分享了一个前端使用AngularJS,后端使用ASP.NET Web API的项目. 源码: https://github.com/chsakell/spa-webapi-angula ...
- Client Dataset Basics
文章出处: http://www.informit.com/articles/article.aspx?p=24094 In the preceding two chapters, I discus ...
- ios 向sqlite数据库插入和读取图片数据
向sqlite数据库插入和读取图片数据 (for ios) 假定数据库中存在表 test_table(name,image), 下面代码将图片文件test.png的二进制数据写到sqlite数据库: ...
- 关于面试总结5-python笔试题(递归)
前言 本篇继续收集一些常见的python笔试题,以基础知识为主,递归是面试最喜欢考的一个问题,不管是做开发还是测试,都无法避免考递归.本篇结合实际案例,讲下几种关于递归的场景. 计算n的阶乘 计算n! ...
- [转]“菜”鸟理解.NET Framework(CLI,CLS,CTS,CLR,FCL,BCL)
既然要学.NET,就要先认识认识她,我不喜欢大段大段文字的东西,自己通过理解,画个图,来看看.NET的沉鱼落雁,闭月羞花之容. 最下层蓝色部分是.NET Framework的基础,也是所有应用软件的基 ...
- 吸血鬼猎人巴菲第一至八季/全集Buffy迅雷下载
本季看点:<吸血鬼猎人巴菲>故事背景在现代,话说于每一个世代都会出现一个年青的女孩子,在人世间寻找及对付一些妖魔鬼怪,例如有吸血鬼.坏女巫等等邪恶的势力,而这个年青的女孩子则被称为Slay ...
- 低版本系统兼容的ActionBar(二)ActionProvider+分离式ActionBar+分离式的ActionMode
这篇文章主要讲的是在低版本兼容的ActionBar中实现自定义的ActionProvider,ShareActionProvider的使用方法,如何实现分离式ActionBar,外加在分 ...
- Python 的 Flask 框架安装应用
Flask是一个使用 Python 编写的轻量级 Web 应用框架.其 WSGI 工具箱採用 Werkzeug ,模板引擎则使用 Jinja2 ,使用 BSD 授权. Flask也被称为 " ...