1、可观察者Observable
1.1、Observable核心要点
- Observable声明的订阅主体,在调用订阅之前并不会执行
- 可以添加无限个next,但每个next在订阅声明后,都会触发一次订阅执行
- next声明的顺序并不代表最终订阅消费执行的顺序,会受到异步代码干扰
-
只有手动确认了complete才会调用complete功函数
- complete之后,如果声明了unSub,则会自动调用unSub函数
- add添加的事件会在unSub之前调用
-
error和complete是互斥的,只会有一个执行
- error会终止后续的订阅事件
- 订阅本身会返回一个subscription,可以简单的调用unsubscribe事件
1.2、简单的使用范式
2.1.1、极简使用范式
const observable = new Observable((subscriber) => {
subscriber.next(1)
subscriber.next(2)
subscriber.next(3)
return () => {
console.log(4);
}
})
const unSub = observable.subscribe(val => {
console.log('val: ', val); // 订阅调用三次:1, 2, 3
})
unSub.add(() => {
console.log(5);
})
unSub.unsubscribe() // result: 1, 2, 3, 4, 5
2.1.2、定制化使用范式
const observable = new Observable((subscriber) => {
console.log('Observable声明的内容,在调用之前不会执行。01')
subscriber.next('可以添加无限个next,每个next都会产生一次订阅消费,会导致subscribe的next执行多次。02')
setTimeout(() => {
subscriber.next('这里是异步执行。03')
subscriber.complete() // 订阅确认执行完成后,如果返回了unsub fn,则会自动执行unsud fn
}, 1000)
subscriber.next('next声明的顺序并不代表订阅执行的顺序,这里是同步的声明,会优先执行。04')
subscriber.add(() => {
console.log('通过add添加的方法会在unsub之前执行。05');
})
subscriber.error('抛出错误会导致后续的订阅事件取消,订阅终止。10') // 此行代码不注释时:07, 01, 02, 04, 10, 05, 06, 09。不会执行:03, 08
return () => {
console.log('可选的订阅解除时执行的内容。06')
}
})
console.log('在订阅消费之前,只是一个声明,所以这里优先执行。07')
observable.subscribe({
next(nextData) {
console.log('nextData: ', nextData);
},
error(err) {
console.log('err: ', err);
},
complete() {
console.log('所有订阅成功执行完成后执行。08');
},
})
console.log('同步执行。09'); // result: 07, 01, 02, 04, 09, 03, 08, 05, 06
2、观察者Observer
Obersver即订阅消费的主体,有两种表现形式
2.1、声明式Observer
- error和complete为可选声明
const observer = {
next(nextValue) {
console.log('do something with nextValue');
},
error(err) {
console.log('do something when got an error');
},
complete() {
console.log('Observer got a complete notigication');
},
}
2.2、极简Observer
observable.subscribe((nextValue) => {
console.log('do something with nextValue:', nextValue);
})
3、操作符Operators
4、订阅Subscription
5、主体Subjects
- 主体Subjects类似于EventEmitter,声明监听器以后,通过next发射参数到监听器进行执行
- Subjects可以多播,即可以声明多个注册器,一次next会有多次响应
- 它类似于JS中的addEventlistener,一次注册以后,通过next触发事件
- 原型方法有:next、error、complete等
- 注:任何在监听器注册订阅之前发出的next都会被忽略
const subject = new Subject()
subject.next(1) // 这里并不会执行,因为监听器尚未注册
subject.subscribe(val => {
console.log('subscriber1: ', val);
})
subject.subscribe(val => {
console.log('subscriber2: ', val);
})
subject.next(2) // 多播,共有两个注册订阅监听器
/*
result:
subscriber1: 2
subscriber2: 2
*/
- fromPromise变更为from - https://github.com/kadoshms/ionic2-autocomplete/issues/169
from(Promise.resolve(11)).subscribe(x => console.log(x)); // 11
- of和range一样,都是Cold Obervable,即每次订阅都谁重复吐出同样的一组数据,可以反复使用。
- 它是同步的,会一口气吐出全部的数据
- 然后调用Observer的complete函数
const source$ = of(1)
// 注意,这里通过参数规定err和complete调用的方式已经启用,转为为声明式的Observer Object
source$.subscribe(x => console.log(x), null, () => {console.log('complete')}); // 1 complete
source$.subscribe(x => console.log(x)); // 1
- repeat依赖于Observable对象的complete完结,完结以后,才会repeat下一次调用
const observable = new Observable(subscribe => {
for (let i = 0; i < 3; i++) {
subscribe.next(i)
}
// subscribe.complete() // 如果此行代码被注释掉,则永远不会发生repeat
})
observable.pipe(repeat(2)).subscribe(v => {
console.log('v: ', v); // 1,2,3
})
- 使用throwError替换throw关键字
- 手动控制takeUntil终止
const notifer$ = new Subject()
interval(1000).pipe(takeUntil(notifer$)).subscribe(v => {
console.log('v: ', v);
}, err => {
console.log('err: ', err);
})
setTimeout(() => {
notifer$.next(1)
notifer$.complete()
}, 4000)