📜  RxJS-使用主题

📅  最后修改于: 2020-10-20 05:36:41             🧑  作者: Mango


主题是一个可观察的对象,可以多播,即与许多观察者交谈。考虑一个按钮,一个事件监听器,使用添加监听器附加到事件的函数被调用每一个按钮类似的功能,用户点击进入为主题太费时间。

我们将在本章中讨论以下主题-

  • 创建一个主题
  • 可观察和主题之间有什么区别?
  • 行为主体
  • 重播主题
  • 异步主题

创建一个主题

要处理主题,我们需要导入主题,如下所示:

import { Subject } from 'rxjs';

您可以如下创建主题对象-

const subject_test = new Subject();

该对象是具有三种方法的观察者-

  • 下一个(v)
  • 错误(e)
  • 完成()

订阅主题

您可以在主题上创建多个订阅,如下所示:

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,与提供给订阅者的值相同。

输出

异步主题