rxjs学习
rxjs中文版--https://cn.rx.js.org/manual/index.html
RxJS 是一个库,它通过使用 observable 序列来编写异步和基于事件的程序。
它提供了一个核心类型 Observable,附属类型 (Observer、 Schedulers、 Subjects) 和受 [Array#extras] 启发的操作符 (map、filter、reduce、every, 等等),这些数组操作符可以把异步事件作为集合来处理。
-
Observable (可观察对象): 表示一个概念,这个概念是一个可调用的未来值或事件的集合。
-
Observer (观察者): 一个回调函数的集合,它知道如何去监听由 Observable 提供的值。
-
Subscription (订阅): 表示 Observable 的执行,主要用于取消 Observable 的执行。
-
Operators (操作符): 采用函数式编程风格的纯函数 (pure function),使用像
map
、filter
、concat
、flatMap
等这样的操作符来处理集合。 -
Subject (主体): 相当于 EventEmitter,并且是将值或事件多路推送给多个 Observer 的唯一方式。
-
Schedulers (调度器): 用来控制并发并且是中央集权的调度员,允许我们在发生计算时进行协调,例如
setTimeout
或requestAnimationFrame
或其他。
注册事件监听器的常规写法。
var button = document.querySelector('button'); button.addEventListener('click', () => console.log('Clicked!'));
使用 RxJS 的话,创建一个 observable 来代替。
var button = document.querySelector('button'); Rx.Observable.fromEvent(button, 'click') .subscribe(() => console.log('Clicked!'));
在angular中使用
import { Subscription, fromEvent } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; _subscription: Subscription;
this._subscription = fromEvent(button,'click') .pipe(debounceTime(50)) //在一顿狂点后只发出最新的点击 .subscribe(() => this.load.emit());
if (this._subscription) { this._subscription.unsubscribe(); }
Observable和Subject的差异
- Observable的每个订阅者之间,读取的发布数据是相对各自独立的。
- Subject的订阅者之间,是共享一个发布数据的。
例如:
Observable
let obs = Observable.create(observer=>{ observer.next(Math.random()); }) obs.subscribe(res=>{ console.log('subscription a :', res); //subscription a :0.2859800202682865 }); obs.subscribe(res=>{ console.log('subscription b :', res); //subscription b :0.694302021731573 });
Subject
let obs = new Subject(); obs.subscribe(res=>{ console.log('subscription a :', res); // subscription a : 0.91767565496093 }); obs.subscribe(res=>{ console.log('subscription b :', res); // subscription b : 0.91767565496093 }); obs.next(Math.random());
从例子中可以看出, Observable 的订阅结果各 不相同,而 Subject 的订阅结果却是 相同 的,这就是把一个值 多播 到订阅者中。
rxjs 搜索案例
rxjs请求案例
combineLatest使用介绍
出处:https://juejin.cn/post/6847902216091598855
import { interval, combineLatest } from 'rxjs'; import { delay, take } from 'rxjs/operators'; const source1 = interval(1000).pipe( take(2) ); const source2 = interval(1000).pipe( delay(1000),take(2) ); const source3 = interval(1000).pipe( delay(3000), take(5) ); combineLatest(source1, source2, source3).subscribe(res => console.log(res)) // 3秒后输出 [1, 1, 0] // 4秒后输出 [1, 1, 1] // 5秒后输出 [1, 1, 2] // 6秒后输出 [1, 1, 3] // 7秒后输出 [1, 1, 4]
当每个流都拿到第一次数据时,combineLatest返回第一次数据; 再后任何一个流拿到了第二次数据时,combineLatest都返顺第二次数据,以此类推;
如上第3秒时source1和source2都没有数据返回了,但source3还会每秒返一个数据,combineLatest也会相应的回返前两参数流最后的值和source3的值有序的数组值
这里核心点,参数流都拿到第一次数据时返回第一次数据,然后只要有参数流任何一个有数据返回combineLatest都返回数据
一个很好的实例: 记账:三个输入框代表三个账的钱,当每个输入框都输了一个数据才会计算总数,有一个记错了修改了一下,总数也跟着变
RxJS中高阶映射操作符的全面讲解:switchMap, mergeMap, concatMap (and exhaustMap)
5 张弹珠图彻底弄清 RxJS 的拉平策略:mergeMap、switchMap、concatMap、exhaustMap
实例讲解zip和combineLatest操作符的区别