主题是一个可观察的对象,可以多播,即可以与许多观察者交谈。考虑带有事件侦听器的按钮,每次用户单击按钮时,都会使用添加侦听器调用附加到事件的功能,类似的功能也适用于主题。
我们将在本章中讨论以下主题:
- 创建一个主题
- 可观察和主题之间有什么区别?
- 行为主体
- 重播主题
- 异步主题
创建一个主题
要处理主题,我们需要导入主题,如下所示:
import { Subject } from 'rxjs';
您可以如下创建主题对象:
const subject_test = new Subject();
该对象是具有三种方法的观察者:
- next(v)
- error(e)
- complete()
订阅主题
您可以在主题上创建多个订阅,如下所示:
subject_test.subscribe({ next: (v) => console.log(`From Subject : ${v}`) }); subject_test.subscribe({ next: (v) => console.log(`From Subject: ${v}`) });
就像我们前面讨论的addlistener一样,订阅已注册到主题对象。
将数据传递给主题
您可以将数据传递给使用next()方法创建的主题。
subject_test.next("A");
数据将传递到主题上添加的所有订阅。
例
这是该主题的一个工作示例:
import { Subject } from 'rxjs'; const subject_test = new Subject(); subject_test.subscribe({ next: (v) => console.log(`From Subject : ${v}`) }); subject_test.subscribe({ next: (v) => console.log(`From Subject: ${v}`) }); subject_test.next("A"); subject_test.next("B");
通过调用新的Subject()创建subject_test对象。subject_test对象引用了next(),error()和complete()方法。上面示例的输出如下所示:
输出
我们可以使用complete()方法来停止主题执行,如下所示。
例
import { Subject } from 'rxjs'; const subject_test = new Subject(); subject_test.subscribe({ next: (v) => console.log(`From Subject : ${v}`) }); subject_test.subscribe({ next: (v) => console.log(`From Subject: ${v}`) }); subject_test.next("A"); subject_test.complete(); subject_test.next("B");
一旦调用完成,就不会调用稍后调用的下一个方法。
输出
现在让我们看看如何调用error()方法。
例
以下是一个工作示例:
import { Subject } from 'rxjs'; const subject_test = new Subject(); subject_test.subscribe({ error: (e) => console.log(`From Subject : ${e}`) }); subject_test.subscribe({ error: (e) => console.log(`From Subject : ${e}`) }); subject_test.error(new Error("There is an error"));
输出
可观察和主题之间有什么区别?
观察者将与订户一对一交谈。每当您订阅可观察的交易时,执行将从头开始。进行一个使用ajax进行的Http调用,并由2个订阅者调用可观察对象。您将在浏览器网络选项卡中看到2个HttpHttp请求。
例
这是相同的工作示例:
import { ajax } from 'rxjs/ajax'; import { map } from 'rxjs/operators'; let final_val = ajax('https://jsonplaceholder.typicode.com/users').pipe(map(e => e.response)); let subscriber1 = final_val.subscribe(a => console.log(a)); let subscriber2 = final_val.subscribe(a => console.log(a));
输出
现在,这里的问题是,我们希望共享相同的数据,但是不希望以2个Http调用为代价。我们要进行一次Http调用,并在订阅者之间共享数据。
使用主题可以做到这一点。这是可以观察到的,可以多播,即与许多观察者交谈。它可以在订户之间共享价值。
例
这是使用主题的工作示例-
import { Subject } from 'rxjs'; import { ajax } from 'rxjs/ajax'; import { map } from 'rxjs/operators'; const subject_test = new Subject(); subject_test.subscribe({ next: (v) => console.log(v) }); subject_test.subscribe({ next: (v) => console.log(v) }); let final_val = ajax('https://jsonplaceholder.typicode.com/users').pipe(map(e => e.response)); let subscriber = final_val.subscribe(subject_test);
输出
现在,您只能看到一个Http调用,并且被调用的订户之间共享相同的数据。
行为主体
行为主题会在调用时为您提供最新值。
您可以创建行为主题,如下所示:
import { BehaviorSubject } from 'rxjs'; const subject = new BehaviorSubject("Testing Behaviour Subject"); // initialized the behaviour subject with value:Testing Behaviour Subject
例
这是使用行为主题的工作示例-
import { BehaviorSubject } from 'rxjs'; const behavior_subject = new BehaviorSubject("Testing Behaviour Subject"); // 0 is the initial value behavior_subject.subscribe({ next: (v) => console.log(`observerA: ${v}`) }); behavior_subject.next("Hello"); behavior_subject.subscribe({ next: (v) => console.log(`observerB: ${v}`) }); behavior_subject.next("Last call to Behaviour Subject");
输出
重播主题
重播主题类似于行为主体,其中,它可以缓冲值并将其重播给新订户。
例
这是重放主题的工作示例:
import { ReplaySubject } from 'rxjs'; const replay_subject = new ReplaySubject(2); // buffer 2 values but new subscribers replay_subject.subscribe({ next: (v) => console.log(`Testing Replay Subject A: ${v}`) }); replay_subject.next(1); replay_subject.next(2); replay_subject.next(3); replay_subject.subscribe({ next: (v) => console.log(`Testing Replay Subject B: ${v}`) }); replay_subject.next(5);
重播主题上使用的缓冲区值为2。因此,最后两个值将被缓冲并用于新的订户。
输出
异步主题
在AsyncSubject的情况下,最后一次调用的值将传递给订阅服务器,并且只有在调用complete()方法之后才能完成。
例
这是相同的工作示例:
import { AsyncSubject } from 'rxjs'; const async_subject = new AsyncSubject(); async_subject.subscribe({ next: (v) => console.log(`Testing Async Subject A: ${v}`) }); async_subject.next(1); async_subject.next(2); async_subject.complete(); async_subject.subscribe({ next: (v) => console.log(`Testing Async Subject B: ${v}`) });
在这里,在调用complete之前,传递给主题的最后一个值为2,并且与提供给订阅者的值相同。
作者:terry,如若转载,请注明出处:https://www.web176.com/rxjs/1759.html