Skip to content

1.基本介绍

参考手册https://www.npmjs.com/package/rxjs

**中文手册:**https://cn.rx.js.org/

RxJS 是 ReactiveX 编程理念的 JavaScript 版本。ReactiveX 来自微软,它是一种针对异步数据流的编程。简单来说,它将一切数据,包括 HTTP 请求,DOM 事件或者普通数据等包装成流的形式,然后用强大丰富的操作符对流进行处理,使你能以同步编程的方式处理异步数据,并组合不同的操作符来轻松优雅的实现你所需要的功能。

RxJS 是一种针对异步数据流编程工具,或者叫响应式扩展编程;可不管如何解释 RxJS 其目标就是异步编程,Angular 引入 RxJS 为了就是让异步可控、更简单。

RxJS 里面提供了很多模块。这里我们主要给大家讲 RxJS 里面最常用的 Observable 和 fromEvent。

注意:RxJS的Observable 和 Promise 很像,但是更加的强大!

2.异步编程方案

目前常见的异步编程的几种方法:

1、回调函数

组件里面使用服务的方法:

js
//2、callback获取异步数据
this.request.getCallbackData((data: any) => {

  console.log(data);
});

服务里面定义的方法:

js
getCallbackData(cb: any) { //传进来一个回调函数,我们异步进行调用,从而实现信息的延迟回传
    setTimeout(() => {
      var username = '张三';

      // return username;
      cb(username);
    }, 1000);
}

2、事件监听/发布订阅

EventEmitter

3、Promise

js
//3、promise获取异步数据
var promiseData = this.request.getPromiseData();
promiseData.then((data) => {
  console.log(data);
})
js
getPromiseData() {
    return new Promise((resolve) => {
      setTimeout(() => {
        var username = '张三--Promise';
        resolve(username);
      }, 3000);
    });
}

注意:async/await 本质上是Promise!

4、Rxjs

3.Rxjs的使用(Observable)

注意:angular里面默认集成了rxjs,不需要安装,直接使用即可!

(1)基本使用

组件里面使用服务的方法:

js
import { RequestService } from '../../services/request.service';

constructor(public request: RequestService) { }

//4、rxjs获取异步方法里面的数据
var rxjsData=this.request.getRxjsData(); //Observable对象
rxjsData.subscribe((data)=>{ //使用subscribe接收数据,相当于.then
    console.log(data);
})

服务里面定义的方法:

js
import { Observable } from 'rxjs';
getRxjsData() {
    return new Observable<any>((observer) => {
      setTimeout(() => {
        var username = '张三--Rxjs';
        observer.next(username); //成功情况的返回,使用next函数,相当于resolve
        // observer.error('数据')  //失败情况的返回,使用error函数,相当于reject
      }, 3000);
    });
}

从上面列子可以看到 RxJS 和 Promise 的基本用法非常类似,除了一些关键词不同。Promise

里面用的是 resolve() 和 then(),而 RxJS 里面用的是 next() 和 subscribe()。

从上面例子我们感觉Promise 和 RxJS 的用法基本相似。其实Rxjs相比Promise 要强大很多。

比如 Rxjs 中可以中途撤回、Rxjs 可以发射多个值、Rxjs 提供了多种工具函数等等。

(2)unsubscribe 取消订阅(不同于ajax取消请求)

Promise 的创建之后,动作是无法撤回的。Observable 不一样,动作可以通过 unsbscribe() 方法中途撤回,而且 Observable 在内部做了智能的处理。

通过unsubscribe可以中途撤回订阅(在实际场景中,请求还是会发出去,只不过接收到的结果我们不往下进行了)

js
getRxjsData() {
    return new Observable<any>((observer) => {
      setTimeout(() => {
        var username = '张三--Rxjs';
        observer.next(username); //这里被拦截了
        // observer.error('数据')
      }, 3000);
    });
}
ts
//5、过一秒以后撤回刚才的操作
var streem = this.request.getRxjsData();

var d = streem.subscribe((data) => {
  console.log(data); //这里就什么都没有了
})

setTimeout(() => {
  d.unsubscribe();  /*1s之后取消订阅*/
}, 1000)

注意:取消订阅是拦截了next函数,不会触发,从根源进行取消!

(3)实现执行多次的异步任务

首先明确:Promise是不具备这个能力的

js
getPromiseIntervalData() {
    return new Promise((resolve) => {
      setInterval(() => {
        //这里面可以是ajax请求等内容
        var username = '张三--Promise  Interval';
        resolve(username); //第一次执行完毕就直接resolve,状态改变之后就不能再触发了
      }, 1000);
    });
}
js
//6、promise 执行多次(没有这个能力)
var intervalData = this.request.getPromiseIntervalData();
intervalData.then((data) => {
  console.log(data); //只会输出一次
})

那么Rxjs如何做?

js
getRxjsIntervalData() {
    let count = 0;
    return new Observable<any>((observer) => {
      setInterval(() => {
        count++;
        //这里面可以是ajax请求等内容
        var username = '张三--Rxjs-Interval' + count;
        observer.next(username);
        // observer.error('数据')
      }, 1000);
    });
}
js
//7、rxjs执行多次
var streemInterval = this.request.getRxjsIntervalData();
streemInterval.subscribe((data) => {
  console.log(data); //不断输出username
})

应用场景:比如爬虫,不断爬取

或者一些需要轮询的场景、不断重复动作的场景等

(4)用管道方法对返回的数据进行拦截处理

**注意:**Angular6 以后使用以前的 rxjs 方法,必须安装 rxjs-compat 模块。

bash
npm install rxjs-compat
js
import { Observable } from 'rxjs';
import 'rxjs/Rx';

如果你不需要对旧版本的 RxJS 操作符保持兼容性,即你的应用程序不使用旧版的 RxJS 操作符,那么就不需要安装 rxjs-compat 模块。

在 Angular 6+ 中,推荐直接导入操作符并按照新的方式使用它们,而不依赖于 rxjs-compat 模块。

js
import { map, filter } from 'rxjs/operators';

使用filter函数进行数据过滤

注意:要套在pipe管道里面,使用相关的函数

js
getRxjsIntervalNum() {
    let count = 0;
    return new Observable<any>((observer) => {
      setInterval(() => {
        count++;
        observer.next(count);
        // observer.error('数据')
      }, 1000);
    });
}
js
//8、用工具方法对返回的数据进行处理
var streemNum = this.request.getRxjsIntervalNum();
streemNum.pipe(
    filter((value) => {
      if (value % 2 == 0) {
        return true;
      }
    	return false;
    })
).subscribe((data) => {
	console.log(data);
});

使用map函数进行数据处理

js
var streemNum = this.request.getRxjsIntervalNum();
streemNum.pipe(
    map((value) => {
      return value * value;
    })
).subscribe((data) => {
    console.log(data);
});

使用 map + filter 进行处理

js
var streemNum = this.request.getRxjsIntervalNum();
streemNum.pipe(
    filter((value) => {
      return value % 2 == 0; //过滤出来偶数
    }),
    map((value) => {
      return value * value; //对每一个数据进行平方
    })
).subscribe((data) => {
    console.log(data);
});

4.实例:rxjs构造路由守卫服务的返回值

路由配置项的canActivate项介绍:

js
canActivate: [RoleGuardScreen]

canActivate 是 Angular 路由模块中的一个路由守卫(Route Guard)。路由守卫用于保护路由,并控制用户是否被允许进入或离开特定的路由。

在上述代码中,canActivate: [RoleGuardScreen] 表示将 RoleGuardScreen 标识为要应用于该路由的路由守卫。

RoleGuardScreen 是一个自定义的路由守卫服务或守卫类的名称。它实现了 CanActivate 接口,该接口定义了一个方法 canActivate(),在导航到某个路由时将被调用。这个方法接受两个参数:routestate,分别表示要导航的目标路由和当前路由状态。

路由守卫在 canActivate() 方法中执行一些逻辑来判断用户是否被允许访问该路由。它可以进行各种验证操作,例如检查用户是否具有特定的角色、权限、认证状态等。如果验证失败,路由守卫可以返回一个 false 值,将用户重定向到其他页面或阻止用户进入该路由。

当路由守卫的 canActivate() 方法返回 true 时,导航继续,用户被允许访问该路由。当返回 false 时,导航被中止,用户被重定向到另一个路由或保持在当前页面。

通过在路由配置中指定 canActivate: [RoleGuardScreen],可以将 RoleGuardScreen 应用于该特定路由,以确保在导航到该路由之前执行相应的验证逻辑并保护该路由。

路由守卫canActivate方法的返回值:

路由守卫的 canActivate() 方法可以返回以下类型之一:

  1. Observable<boolean>:当路由守卫需要异步处理时,可以返回一个 Observable 对象,并在 Observable 中使用 next() 发射一个布尔值来指示是否允许导航。Observable 可以发出多个值,但当它发出 false 时,导航将被取消。当 Observable 完成时,导航将继续。
  2. Promise<boolean>:可以返回一个 Promise 对象,它可以异步确定是否允许导航。当 Promise 的解析值为 false 时,导航将被取消。解析值为 true 或 Promise 完成时,导航将继续。
  3. boolean:可以直接返回一个布尔值。true 表示允许导航,false 表示取消导航。

需要注意的是,如果返回值是一个 Observable 对象或 Promise 对象,Angular 路由模块会等待该 Observable 或 Promise 完成,然后根据返回值来决定是否允许导航。

服务的构造:

ts
import { Route } from '@angular/compiler/src/core';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree } from '@angular/router';
import { HttpService } from '@services';
import { Observable } from 'rxjs';
import { NzMessageService } from 'ng-zorro-antd/message';
@Injectable({ providedIn: 'root' })
export class RoleGuardScreen implements CanActivate {
    constructor(
        private route: Router,
        private httpService: HttpService,
        private router: Router,
        public message: NzMessageService,
    ) {}
    // eslint-disable-next-line @typescript-eslint/member-ordering
    public roleId: any;

    getRoleId() {
        const cookieTpl = document.cookie.split('; ');
        cookieTpl.forEach((item) => {
            if (item.indexOf('role-code') !== -1) {
                const newArr = item.split('=');
                this.roleId = newArr[1]; //得到cookie里面的角色id
                console.log('this.roleId', this.roleId);
            }
        });
    }

    canActivate( //路由守卫,默认canActivate: [RoleGuardScreen],会调用这个方法
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot,
    ): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
        this.getRoleId();
        return this.checkRole(this.roleId);
    }

    // 低权限
    checkRole(roleId): Observable<any> | UrlTree | boolean { 
        console.log('roleId', roleId);
        if (roleId === '2') {
            location.hash = '/cloud-soc/report/audit/soc-log'; //如果id为2就跳转到特定的路径:将浏览器的 URL 锚点(hash)设置为 '/cloud-soc/report/audit/soc-log' 。这实际上是一种改变浏览器地址栏中的 URL,并触发浏览器进行相应的页面跳转。
            // return this.router.parseUrl('/cloud-soc/report/');
        } else {
            return new Observable((observer) => {
                observer.next(true);
                observer.complete();
            });
        }
    }
}

canActivate 是一个路由守卫方法,它决定是否允许用户导航到特定路由。在 canActivate 方法中,你调用了 getRoleId() 方法来获取用户的角色信息,并将角色 ID 传递给 checkRole() 方法来检查用户的权限。

现在让我们讨论为什么使用 RxJS Observable 作为返回类型。在 Angular 中,canActivate 方法可以返回一个布尔值、一个 UrlTree 对象、一个 Observable 或一个 Promise。这样设计是为了允许开发者在权限检查过程中执行异步操作,比如从服务器获取权限信息。 ——> 这是angular路由的默认规定!

在这里,canActivate 方法返回了一个 Observable 对象:

ts
return new Observable((observer) => {
    observer.next(true);
    observer.complete();
});

Observable 发出一个值为 true 的 next 通知,然后立即完成(complete)。这样做的效果是立即允许导航。

使用:

js
{
    path: 'overview',
    data: { breadcrumb: '运营报告' },
    component: ReportOverviewComponent,
    canActivate: [RoleGuardScreen],
},
{
    path: 'audit',
    data: { breadcrumb: '审计日志' },
    component: ReportLayoutComponent,
    children: [
        {
            path: 'soc-log',
            data: { breadcrumb: 'SOC审计日志' },
            component: SocAuditLogComponent,
        },
        {
            path: 'sse-log',
            data: { breadcrumb: 'SSE审计日志' },
            component: DeviceAuditLogComponent,
        },
        // {
        //     path: 'user-log',
        //     data: { breadcrumb: '用户审计日志' },
        //     component: UserAuditLogComponent,
        // },
        {
            path: '',
            redirectTo: 'soc-log',
        },
    ],
    canActivate: [RoleGuard],
},

5.Observable和Subject

Subject是什么,有什么特点?

在RxJS(Reactive Extensions for JavaScript)中,Subject 是一种特殊类型的 Observable,同时也是一个观察者(Observer)。它允许多个观察者订阅它,并且可以通过调用 next, error, 和 complete 方法来从外部向它推送新的值,错误信息或者完成信号。——> 它相当于是一个Observable与Observer之间的中间商!

主要特点包括:

  1. 多播性(Multicasting)Subject 是一种多播的 Observable,意味着它可以同时向多个观察者传播数据

    当你调用 next 方法时,所有订阅该 Subject 的观察者都会接收到新的数据。

  2. 状态维护Subject 会维护当前值,并在使用next方法时将最新值立即发送给它们,这对于在任何时候加入应用程序的新观察者是有用的。

  3. 可以作为观察者Subject 既是 Observable 又是 Observer。它可以订阅其他 Observables,并可以被其他 Observers 订阅(作为中间商)

  4. 不是纯粹的函数式编程模型: 与纯粹的函数式编程模型不同,Subject 允许在程序中引入可变状态,因为它允许通过调用 next 方法来推送新值。

**使用 Subject 可以实现多个部分共享同一份数据流,从而使得多个部分能够响应同一个数据源的变化。**然而,要注意在使用时适当地处理状态和副作用,以确保程序的可维护性和一致性。

js
import { Subject } from 'rxjs';

const subject = new Subject<number>(); //不需要传递回调函数,和Observable窗口的时候不同

// 订阅 Subject
const subscription = subject.subscribe((value) => {
  console.log('Received value:', value);
});

// 推送新值给所有订阅者(不用在回调函数里面推送)
subject.next(1);
subject.next(2);

// 取消订阅
subscription.unsubscribe();

Observable与Observer对比?分别是什么?

我们在写Observable时一般都是这么写:其实它的回调函数的参数就是Observer

js
new Observable<any>((observer) => {
  setTimeout(() => {
    var username = '张三--Rxjs';
    observer.next(username); //成功情况的返回,使用next函数,相当于resolve
    // observer.error('数据')  //失败情况的返回,使用error函数,相当于reject
  }, 3000);
});
  1. Observable: Observable 是一个表示数据流的对象,它可以被观察,可以被订阅以接收它发出的值。Observable 可以发出零个、一个或多个值,也可以在完成时发出完成信号或在出现错误时发出错误信息。

  2. Observer: Observer 是用于监听 Observable 发出的值、完成信号或错误信息的对象。它通常由三个回调函数组成:

    • next: 处理 Observable 发出的新值。

    • error: 处理 Observable 发出的错误。

    • complete: 处理 Observable 发出的完成信号。

      注意:以上方法是没有返回值的!

js
let subscription = rxjsData.subscribe((data)=>{ //使用subscribe接收数据,相当于.then
    console.log(data);
})

subscribe: subscribe 是 Observable 上的方法,用于订阅 Observable。当你订阅一个 Observable 时,你会得到一个 Subscription 对象,该对象可以用于取消订阅。

Observable和Subject的对比?

ObservableSubject 是 RxJS 中两个重要的概念,它们用于处理异步数据流和实现响应式编程。以下是它们的对比:

一、Observable(可观察对象):

  1. 单播(Unicast)
    • Observable 是单播的,每个订阅者(Observer)都会创建一个新的执行路径。
  2. 不可变
    • Observable 本身是不可变的,它不会发出任何数据,只有通过调用 next, error, 和 complete 方法才能向观察者发出数据、错误或者完成信号。
  3. 推送数据
    • 通过 next 方法向订阅的观察者推送新的数据。
  4. 订阅和取消订阅
    • 使用 subscribe 方法订阅 Observable,返回一个 Subscription 对象,可以用于取消订阅以停止接收数据。
  5. 冷 Observable
    • Observable 在被订阅时才开始执行,每个订阅者都有独立的执行路径。

二、Subject(主题):

  1. 多播(Multicast)
    • Subject 是多播的,它可以同时将数据推送给多个订阅者。
  2. 可变
    • Subject 是可变的,可以通过调用 next, error, 和 complete 方法向观察者发出数据、错误或者完成信号。
  3. 推送数据
    • 通过 next 方法向所有订阅的观察者推送新的数据。
  4. 订阅和取消订阅
    • 使用 subscribe 方法订阅 Subject,返回一个 Subscription 对象,可以用于取消订阅以停止接收数据。
  5. 热 Observable
    • Subject 是热 Observable,它可以在任何时候发出数据,不受订阅时间的影响。

三、选择使用时的考虑因素:

  • 如果你需要创建一个可观察对象,并且希望每个订阅者都有独立的执行路径,使用 Observable
  • 如果你想要创建一个可以多播给多个订阅者的数据源,并且希望新的观察者可以接收到最新的值,使用 Subject 或者 BehaviorSubject
  • 如果你需要一个特殊类型的 Subject,它可以记录最新的值并在新的订阅者订阅时立即推送该值,使用 BehaviorSubject
  • 如果你需要一个特殊类型的 Subject,它可以记录推送的所有值的日志,使用 ReplaySubject
  • 如果你需要一个特殊类型的 Subject,它可以只向后续订阅者推送最新值,使用 AsyncSubject

注意:可以说Observable类似于Promise,而Subject类似于Pubsub.js!!!——> 很巧妙的比喻

1.Observable 类比于 Promise:

  • ObservablePromise 都用于处理异步操作,提供了一种处理异步操作结果的方式。
  • Promise 主要用于一次性的异步操作,可以获取成功的结果或失败的原因,而 Observable 更适用于表示持续的异步数据流。
  • Observable 具有丰富的操作符,可以对数据流进行转换、过滤、组合等处理,而 Promise 只能通过 .then().catch() 处理结果。

2.Subject 类比于 PubSub.js 插件:

  • SubjectPubSub.js 插件类似,都支持多个订阅者(观察者)。
  • Subject 是 RxJS 中的一种特殊类型,可以作为 Observable 也可以作为 Observer,同时也具有多播的能力,类似于 PubSub 的多播特性。
  • PubSub.js 插件实现了简单的发布-订阅模式,它允许你发布事件,然后订阅这些事件的通知,和 Subject 在某种程度上有相似之处。

在这种比较下,可以说 Subject 在一些方面类似于 PubSub.js 插件,但是 Subject 是 RxJS 中的一种工具,具有更丰富的特性和功能,适用于处理更复杂的异步数据流。而 PubSub.js 插件是一个简单的发布-订阅模式的实现,适用于简单的事件通知场景。

6.RxJS中的四种Subject

简介: RxJS中有四种不同类型的Subject,它们分别是Subject、BehaviorSubject、ReplaySubject和AsyncSubject。本文将介绍这四种Subject的用法、区别以及适用的应用场景,并提供代码示例。

RxJS(Reactive Extensions for JavaScript)是一个功能强大的响应式编程库,它提供了许多强大的工具和概念来处理异步数据流。

在RxJS中,Subject是一个重要的概念,它充当了一个可观察对象和观察者之间的桥梁(具体详见深入浅出 RxJS 核心原理(响应式编程篇))。

RxJS中有四种不同类型的Subject,它们分别是Subject、BehaviorSubject、ReplaySubject和AsyncSubject。本文将介绍这四种Subject的用法、区别以及适用的应用场景,并提供代码示例。

一、Subject

Subject是最简单的一种Subject类型。它既是可观察对象(Observable),也是观察者(Observer)。Subject会维护一个观察者列表,并将它们通知给任何订阅它的观察者。

常见用法示例:

  1. 基本使用
ts
import { Subject } from 'rxjs';

const subject = new Subject<number>();

// 订阅 Subject
const subscription = subject.subscribe((value) => {
  console.log('Received value:', value);
});

// 推送新值给所有订阅者
subject.next(1);
subject.next(2);

// 取消订阅
subscription.unsubscribe();
  1. 多播(Multicasting)

Subject 可以实现多播,即多个观察者同时收到相同的数据。

ts
import { Subject } from 'rxjs';

const subject = new Subject<number>();

// 多个观察者订阅同一个 Subject
subject.subscribe((value) => {
  console.log('Observer 1 received:', value);
});
subject.subscribe((value) => {
  console.log('Observer 2 received:', value);
});

// 推送新值给所有订阅者
subject.next(1);
subject.next(2);
  1. 将 Subject 作为 Observable,使用.asObservable()函数

你可以将 Subject 当作一个普通的 Observable 来使用。

ts
import { Subject } from 'rxjs';

const subject = new Subject<number>();

subject.subscribe((value) => {
  console.log('Observer 1 received:', value);
});

subject.next(1);

// 也可以将 Subject 当作 Observable 使用
subject.asObservable().subscribe((value) => {
  console.log('Observer 2 received:', value);
});

subject.next(2);
  1. 错误处理(和Observable一样的)

Subject 也可以处理错误信息。

ts
import { Subject } from 'rxjs';

const subject = new Subject<number>();

subject.subscribe(
  (value) => console.log('Received value:', value),
  (error) => console.error('Error:', error)
);

subject.next(1);
subject.error('Something went wrong!');

这些示例展示了 Subject 的一些常用用法,包括基本的订阅、多播、将 Subject 作为 Observable 使用以及错误处理。Subject 的灵活性使其成为 RxJS 中强大的工具,可以用于多种场景,特别是在多个观察者需要同时观察同一数据流的情况下。

应用场景:

  • 在需要将一个值或事件广播给多个观察者的场景中使用Subject。
  • 当需要将已存在的非RxJS代码转化为响应式时,Subject是一个不错的选择。

二、BehaviorSubject

BehaviorSubject是一种特殊类型的Subject,它会记住最新的值,并在有新的观察者订阅时立即将这个最新值发送给它们(subject在订阅时不会推送值,而是在下一次进行next的时候才推送)

用法示例:

javascript
const behaviorSubject = new BehaviorSubject('Initial value'); //可以传递一个初始值,作为当前默认的最新值

behaviorSubject.subscribe((data) => { //订阅之后立即收到初始值
  console.log('Observer 1:', data);
});

behaviorSubject.next('Hello');

behaviorSubject.subscribe((data) => { //订阅之后立即收到当前的最新值(即上一次next的值)
  console.log('Observer 2:', data);
});

输出结果:

yaml
Observer 1: Initial value
Observer 1: Hello
Observer 2: Hello

应用场景:

  • 当需要将当前状态或初始值发送给新的观察者时,可以使用BehaviorSubject。
  • 在状态管理中,BehaviorSubject可以用作存储和访问状态的中心数据源。

三、ReplaySubject

ReplaySubject会在有新的观察者订阅时,向它们发送之前发送过的数据,可以指定发送的历史数据数量。

用法示例:

javascript
const replaySubject = new ReplaySubject(2);

replaySubject.subscribe((data) => {
  console.log('Observer 1:', data);
});

replaySubject.next('Value 1');
replaySubject.next('Value 2');
replaySubject.next('Value 3');

replaySubject.subscribe((data) => {
  console.log('Observer 2:', data);
});

输出结果:

bash
mathematicaCopy code
Observer 1: Value 1
Observer 1: Value 2
Observer 1: Value 3
Observer 2: Value 2
Observer 2: Value 3

应用场景:

  • 当需要将过去的数据重新发送给新的观察者时,可以使用ReplaySubject。
  • 在需要缓存历史数据的场景中,ReplaySubject非常有用。

四、AsyncSubject

AsyncSubject只会在Subject完成时发送最后一个值给观察者。如果Subject还没有完成,那么AsyncSubject不会发送任何值。

用法示例:

javascript
const asyncSubject = new AsyncSubject();

asyncSubject.subscribe((data) => {
  console.log('Observer 1:', data);
});

asyncSubject.next('Value 1');
asyncSubject.next('Value 2');
asyncSubject.next('Value 3');

asyncSubject.subscribe((data) => {
  console.log('Observer 2:', data);
});

asyncSubject.complete();

输出结果:

yaml
Observer 1: Value 3
Observer 2: Value 3

应用场景:

  • 当只关心Subject完成后的最终结果时,可以使用AsyncSubject。
  • 在需要等待异步操作完成后获取结果的场景中,AsyncSubject非常适用。

总结

在开发中我们常用的是Subject,但是一些场景中我们还是需要根据具体情况来使用。

Subject类型用法区别适用场景
Subject将值或事件广播给多个观察者无法回放历史数据- 广播值或事件给多个观察者 - 将非RxJS代码转换为响应式
BehaviorSubject将最新值发送给新的观察者记住最新值- 初始值或当前状态的广播 - 状态管理的中心数据源
ReplaySubject向新的观察者发送历史数据可以回放历史数据- 重新发送过去数据给新的观察者 - 缓存历史数据的场景
AsyncSubject在完成时发送最后一个值只发送最后一个值- 只关心Subject完成后的最终结果 - 等待异步操作完成后获取结果

希望本文能帮助您更好地理解RxJS中四种Subject的用法和区别,并在实际开发中正确地应用它们。