rxjs 学习(1)-认识 rxjs 和理解 observables

什么是 rxjs?

我查阅了一些资料,以为比较通俗易懂的说法是:rxjs 是一个使用 Observable 的响应式编程库。它经过使用 observable 序列编写基于异步和事件的程序。核心类型是: Observable , 附属类型:Observer, Schedules, Subjects 和一些操做符 map,filter等。这些操做符能够把异步事件看成集合处理。咱们能够把rxjs 看成用来处理事件的 lodash;javascript

lodash 是一个一致性、模块化、高性能的 js 实用工具库,它的内部封装了不少字符串,数组,对象等常见类型的函数。java

如何理解 Observable?

说到 Observable,可能咱们得先了解一下异步编程的历史。ajax

  • 最开始的时候,采用的是 callback 回调的方式,注册回调函数,等异步请求返回会后,把数据传入回调函数,对异步请求的结果进行处理。可是若是出现多个异步嵌套,就会出现可怕的回调地狱。
  • promise 的出现缓解了“callback hell”的问题。它承诺在必定的时间内,会完成事件或者是抛出错误。在代码执行时只须要监听这两种状态就能够了。可是也有弊端,同步和异步代码分离很差,代码可读性查,而且它一次只能处理一个事件,随着程序变大,promise 也会变得很是难管理。
  • 最新的 es2017 中出现了 async/await 的写法,它并非一个新的功能,能够看做是 promise 的语法糖。可是依然没有改变同步代码和异步代码混用的局面。

对于数据传输的更具体地叙述可见:编程

此时 Observable 这种响应式的把同步异步代码都看成异步来操做的响应式编程就产生了。数组

rxjs 中的 Observable,说通俗一点,就是一个数据或是不少个事件组成在一块儿的数据流。rxjs 提供了不少操做这些数据流的方法,那就是操做数,好比 map,filter等。 如今咱们来初步了解一下 Observable 吧。promise

关于 rxjs 的基础知识

既然上面说到了 Observable 是 rxjs 的核心类型,因此咱们就来好好了解一下 observable 吧。异步

Observables 的产生来源

Observable 是数据流,它的产生有两种,一种是来自于已有的数据,将其转换成 observable; 还有一种是从无到有,直接建立 observable。这种感受就像:我想要送给朋友一件礼物,能够选择本身手动 DIY, 也能够到淘宝买一份,而后包装。async

从别的数据转换过来的方式有:模块化

  • 来自一个或多个值,能够直接用 of(value) 转化: Rx.Observable.of('haha','xixi');
  • 来自数组, 使用 from(array) 转换: Rx.Observable.from([1,2,3]);
  • 来自事件, 使用 fromEvent(element,event) 转换: Rx.Observable.fromEvent(document.querySelector('button'), 'click');
  • 来自 Promise, 使用 fromPromise() 转换:Rx.Observable.fromPromise(fetch('/users'));
  • 来自 callback,bindCallback():Rx.Observable.bindCallback(fs.exists);

本身建立 observables 的有:异步编程

  1. 在外部产生新事件
import { Observable, BehaviorSubject, Subject } from 'rxjs';
const myObservable = new Subject();
myObservable.subscribe(value => console.log(value));
myObservable.next('haha');
  1. 在内部产生新事件
var myObservable = Rx.Observable.create(observer => {
  observer.next('haha');
  setTimeout(() => observer.next('xixi'), 1000);
});
myObservable.subscribe(value => console.log(value));

选择哪一种方式须要根据场景。当你想要包装随时间推移产生值的功能时,普通的 Observable 就已经很好了。使用 Subject,你能够从任何地方触发新事件,而且将已存在的 observables 和它进行链接。

控制 Observables 数据流的流动过程

以在 input 框中输入 "hello world” 为例

const input = Rx.Observable.fromEvent(document.querySelector('input','input'));
  • 过滤掉小于3个字符长目标值
input.filter(event => event.target.value.length > 2)
    .map(event => event.target.value)
    .subscribe(value => console.log(value))// "hel"
  • 延迟事件
input.delay(200)
    .map(event => event.target.value)
    .subscribe(value => console.log(value));
  • 中止输入后 200ms 方能经过最新的那个事件
input.debounceTime(200)
    .map(event => event.target.value)
    .subscribe(value => console.log(value));
  • 取前 3 次事件流,在3次事件流后中止事件流
input.take(3)
    .map(event => event.target.value)
    .subscribe(value => console.log(value));// hel
  • 直到其余 observable 触发事件才中止事件流
const stopStream = Rx.Observable.fromEvent(document.querySelector('button','click'));
input.takeUntil(stopStream)
    .map(event => event.target.value)
    .subscribe(value => console.log(value));// hello ,点击才能看到

处理产生的值

仍是以上个代码为例:输入 “hello world"

const input = Rx.Observable.fromEvent(document.querySelector('input'),'input');
// 传递一个值,不作处理
input.map(event => event.target.value)
    .subscribe(value => console.log(value));// 'h'

// 经过提取属性产生一个新的值
input.pluck('target','value')
    .subscribe(value => console.log(value));// 'h'
// 传递以前的两个值
input.pluck('target','value').pairwise()
    .subscribe(value => console.log(value));// ['h','he']

// 只会经过惟一的值
input.pluck('data').distinct()
    .subscribe(value => console.log(value));// 'helo wrd'

// 不会传递与上一个重复的值
input.pluck('data').distinctUntilChanged()
    .subscribe(value => console.log(value)); // 'helo world'

因此,综上可得,一个 observable 在程序中通过了产生 --> 控制流动方式 --> 最后产生的值的处理 --> 订阅 的四大过程。

相关文章
相关标签/搜索