携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
Subject
Subject是一个Observable,也是一个Observer,它可以同时接收Observable发射出数据,也可以向订阅它的Observer发射数据,同时,Subject会对内部的Observer清单进行多播(Multicast)。
Subject是一个神奇的对象,简单来说,它是一个Observable,同时也是一个Observer,它可以发射数据,它也可以监听到发射的数据。也就是,它发射数据,它自己也监听到发射的数据。注意这里,是自己发射数据,自己监听到自己发射的数据,并不是监听别人发射的数据。简单来说,就是发布者和订阅者的结合体。
上面提到了多播,有多播肯定会有单播,总结一下单播,多播,广播的区别:
- 单播:一对一;
- 多播:一对多,有先后顺序;
- 广播:一对多,无向后顺序;
其实主要区别就是订阅者是单个还是多个,多个订阅者的时候是否有先后顺序。
const { Subject } = require('rxjs');
let subject = new Subject();
subject.next('Hello');
subject.subscribe((data) => {
console.log(data);
});
subject.next('Tom');
subject.subscribe((data) => {
console.log(data);
});
subject.next('Jerry');
看到这里,是不是觉得它和Vue2里的vm.on有点相似呢?的确是有点像,原理也是一样的,都是采用了发布订阅模式。一起来看下吧。
<template>
<button @click="handleClick">触发事件</button>
</template>
<script>
export default {
data() {
return {
message: 'hello vue'
}
},
created() {
this.$on('my_event1', () => {
......
})
},
methods: {
handleEvents(e) {
console.log(this.message, e)
},
handleClick() {
this.$emit('my_event1', 'my params')
}
}
}
</script>
上面的例子中,Vue组件实例派发了一个事件,在created钩子中监听了这个事件,谁派发,谁监听。
Subject有三个变体,分别是BehaviorSubject,ReplaySubject,AsyncSubject,前两个在日常工作中用的多一点。
BehaviorSubject
BehaviorSubject是一种在有新的订阅时会额外发出最近一次改变的值的Subject,需要传入一个参数作为初始值。
const { BehaviorSubject } = require('rxjs');
let subject = new BehaviorSubject('Hello');
subject.subscribe((data) => {
console.log(data);
});
subject.next('Tom');
subject.subscribe((data) => {
console.log(data);
});
ReplaySubject
ReplaySubject会记录所有的值,然后回放给新的订阅者,需要传入一个参数用于控制回放值的数量。
const { ReplaySubject } = require('rxjs');
let subject = new ReplaySubject(2);
subject.next('Tom');
subject.subscribe((data) => {
console.log(data);
});
subject.next('Jerry');
subject.subscribe((data) => {
console.log(data);
});
AsyncSubject
AsyncSubject 只有当 Observable 执行完成时(执行complete()),它才会将执行的最后一个值发送给观察者,如果因异常而终止,AsyncSubject将不会释放任何数据,但是会向Observer传递一个异常通知。
const { AsyncSubject } = require('rxjs');
let subject = new AsyncSubject();
subject.subscribe((data) => {
console.log(data);
});
subject.next('Hello');
subject.next('Tom');
subject.subscribe((data) => {
console.log(data);
});
subject.next('Jerry');
subject.complete();
console.log(666);
“热”的Observable和“冷”的Observable,也是很有意思的,下一篇文章见吧。