异步数据流的响应式编程库Rxjs(四)核心概念Subject

129 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 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.emitvm.emit和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有三个变体,分别是BehaviorSubjectReplaySubjectAsyncSubject,前两个在日常工作中用的多一点。

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,也是很有意思的,下一篇文章见吧。