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. STM32 F4 DAC DMA Waveform Generator

    STM32 F4 DAC DMA Waveform Generator Goal: generating an arbitrary periodic waveform using a DAC with ...

  2. IAR EWARM Checksum Technical Note

    IELFTOOL Checksum - Basic actions EW targets: ARM, RH850, RX, SH, STM8 EW component: General issues ...

  3. Java深入 - 深入 Java自己定义注解

    我们在使用Spring框架的时候,会常常使用类似:@Autowired 这种注解. 我们也能够自定义一些注解.Java的注解主要在包:java.lang.annotation中实现. 1. 元注解 什 ...

  4. delphi dxRibbon中 F10快捷键不好用的原因

    最近在项目中使用ribbon  ,用F10做快捷键,但是不好用, 不好用的原因是dxBarManager1 中的有个选项UseF10ForMenu, 把这项关闭就可以了

  5. 移植Python2到TQ2440

    环境 Python:2.7.13 开发板: TQ2440 工具链: arm-none-linux-gnueabi-gcc 4.8.3 概述 前面已经把Python3移植到TQ2440上面的,现在我们移 ...

  6. 在ASP.NET MVC实现购物车,尝试一种不同于平常的购物车显示方式

    通常,我们看到的购物车是这样的: 虽然这种购物车显示方式被广泛运用,但我个人觉得不够直观.如果换成这样呢? 本篇的源码放在了:https://github.com/darrenji/ShoppingC ...

  7. value stored to value2 during its initialization is never read

    警告:value stored to value2 during its initialization is never read NSMutableArray *datesArray = [[NSM ...

  8. 【转】iPhone易被窃听应用三分钟即可获取所有信息

    2011年8月9日10:19 “你有iPhone吗?这下你麻烦了!”昨天香港<东方日报>封面文章用这样的语气报道说,一种iPhone等智能手机窃听程序,正引爆香港. 该报记者亲自试验,发现 ...

  9. Git:常用命令(二)

    查看提交历史 git log 撤消操作 任何时候,你都有可能需要撤消刚才所做的某些操作.接下来,我们会介绍一些基本的撤消操作相关的命令.请注意,有些操作并不总是可以撤消的,所以请务必谨慎小心,一旦失误 ...

  10. 多个类定义attr属性重复的问题:Attribute "xxx" has already been defined

    有时候做自定义控件时就会遇到命名冲突,改变有冲突的名字自然是最直接有效的方式,但是感觉很傻.我搜了下别人的解决方案,觉得很值得借鉴.就是把重名的属性,独立出来写一下,然后在定义时直接写属性名字即可. ...