Observable、Observer 和 Subject

118 阅读1分钟

1. Observable (可观察对象)

Observable 代表一个数据流,是数据的生产者。

需要创建新的数据源、封装异步操作时使用

特点

  • 惰性:只有被订阅时才开始执行
  • 可发出多个值next、error、complete信号
  • 像是一个函数,但是可以返回流式数据

创建和使用

import { Observable } from 'rxjs';
​
// 创建一个 Observable
const newspaper$ = new Observable(subscriber => {
  console.log('报社开始工作');
  
  // 生产数据
  subscriber.next('头条新闻');
  subscriber.next('体育新闻');
  subscriber.next('财经新闻');
  
  // 完成
  subscriber.complete();
  
  // 清理函数
  return () => {
    console.log('报社停止工作');
  };
});
​
// Observable 创建后不会立即执行,需要订阅
console.log('还没有人订阅报纸');

2. Observer(观察者)

Observer 是数据的消费者,定义如何处理数据。

特点

一个包含三个回调函数的对象

  • next(value)
  • error(err)
  • complete()

创建和使用

// 创建一个 Observer(读者)
const reader: Observer<string> = {
  next: (news) => console.log(`读者收到新闻: ${news}`),
  error: (err) => console.error(`送报出错: ${err}`),
  complete: () => console.log('今天的报纸已送达完毕')
};
​
// 订阅 Observable(读者向报社订阅)
const subscription = newspaper$.subscribe(reader);
​
// 输出:
// 报社开始工作
// 读者收到新闻: 头条新闻
// 读者收到新闻: 体育新闻
// 读者收到新闻: 财经新闻
// 今天的报纸已送达完毕
// 更常见的简写方式
newspaper$.subscribe(
  news => console.log(`收到新闻: ${news}`),     // next
  err => console.error(`错误: ${err}`),         // error
  () => console.log('报纸送达完毕')              // complete
);

3. Subject(主体)

Subject 既是 Observable,同时也是 Observer。

典型场景:需要手动控制数据流、实现多播、事件总线时(多播 就是Hot Observable, 多个观察者共享一个数据执行)

特点

  • 多播: 可以将数据广播给多个观察者
  • 既是数据生产者也是消费者
  • 热 Observable:数据生产不依赖于订阅

使用

import { Subject } from 'rxjs';
​
// 创建 Subject(像新闻通讯社)
const newsAgency = new Subject<string>();
​
// 作为 Observable 使用 - 可以被订阅
const reader1 = newsAgency.subscribe(
  news => console.log(`读者1收到: ${news}`)
);
const reader2 = newsAgency.subscribe(
  news => console.log(`读者2收到: ${news}`)
);
​
// 作为 Observer 使用 - 可以产生数据
newsAgency.next('突发新闻:重大事件!');
newsAgency.next('体育:比赛结果');
​
// 输出:
// 读者1收到: 突发新闻:重大事件!
// 读者2收到: 突发新闻:重大事件!
// 读者1收到: 体育:比赛结果
// 读者2收到: 体育:比赛结果

结合使用

Subject 作为Observer 使用

import { Observable, Subject } from 'rxjs';
​
// 1. 创建原始 Observable(原始数据源)
const rawNews$ = new Observable<string>(subscriber => {
  console.log('记者开始采访');
  subscriber.next('现场报道1');
  subscriber.next('现场报道2');
  setTimeout(() => {
    subscriber.next('最新进展');
    subscriber.complete();
  }, 1000);
});
​
// 2. 创建 Subject(新闻编辑中心)
const newsEditor = new Subject<string>();
​
// 3. 多个 Observer(读者)
newsEditor.subscribe(news => console.log(`📰 读者A: ${news}`));
newsEditor.subscribe(news => console.log(`📰 读者B: ${news}`));
​
// 4. 连接:原始数据源 -> 编辑中心 -> 读者
console.log('开始新闻分发...');
rawNews$.subscribe(newsEditor); 
​