我正在研究Angular RxJs模式,我不明白行为主体和可观察对象之间的区别。

根据我的理解,BehaviorSubject是一个可以随时间变化的值(可以订阅,订阅者可以接收更新的结果)。这似乎与可观察对象的目的完全相同。

什么时候使用可观察对象和行为主体?使用一个行为主体比使用一个可观察对象有好处吗?反之亦然?


当前回答

在rxjs中,Subject本质上是一个观察者和可观察对象。观察者是我们放入值的对象,可观察对象是我们可以观察值的对象。

Subject is Hot by default. Observables by default are cold. That means they are not going to emit any values until someone subscribes to it. The instant we create a subject, we can emit a value from it and that value will be emitted even if nobody is subscribed to it yet. Subject is multicast by default. Observable by default are unicast and that means that for every different observer that we have, we have to subscibe to an observable, if that observable emits a value that value is going to flow through all the different operators inside of our pipe once for each subscriber. Multicast means all of other operators will run one time for every value, regardless of the number of observers we have. GOTCHA= thE SUBJECT is multicast but if you chain on a pipe statement to it, that is going to return a new observable that is cold and unicast.

行为主体与主体相同,但也有初始的“种子”值。新订阅用户立即获得最新的值。如果有人订阅了行为主体,它会立即接收到最近的值。所以行为主体总有一些价值可以分给订阅者。

关于行为主体最有用的事情是当我们开始发出网络请求时。想象一下,我们将一些管道连接到一个行为主题上,在一个管道函数或管道操作符中,我们最终发出一个网络请求并获取一些数据。你最终可能会想让其他东西订阅那个可观察对象,并立即获得已经获取的数据。使用行为主体,我们可以很容易地实现这种行为。

其他回答

app.component.ts

behaviourService.setName("behaviour");

behaviour.service.ts

private name = new BehaviorSubject("");
getName = this.name.asObservable();

constructor() {}

setName(data) {
    this.name.next(data);
}

custom.component.ts

behaviourService.subscribe(response=>{
    console.log(response);    //output: behaviour
});

我在例子中没有看到的一件事是,当你通过asObservable将BehaviorSubject转换为Observable时,它继承了订阅时返回最后一个值的行为。

这是很棘手的一点,因为库通常会将字段作为可观察对象公开(例如,在Angular2中ActivatedRoute中的参数),但可能会在幕后使用Subject或BehaviorSubject。他们使用什么会影响订阅行为。

请看这里http://jsbin.com/ziquxapubo/edit?html,js,console

let A = new Rx.Subject();
let B = new Rx.BehaviorSubject(0);

A.next(1);
B.next(1);

A.asObservable().subscribe(n => console.log('A', n));
B.asObservable().subscribe(n => console.log('B', n));

A.next(2);
B.next(2);

BehaviorSubject

BehaviorSubject构建在与我们的ReplaySubject相同的功能之上,比如,hot,并重放先前的值。

BehaviorSubject又增加了一个功能,您可以给BehaviorSubject一个初始值。让我们继续,看看这段代码

import { ReplaySubject } from 'rxjs';

const behaviorSubject = new BehaviorSubject(
  'hello initial value from BehaviorSubject'
);

behaviorSubject.subscribe(v => console.log(v));

behaviorSubject.next('hello again from BehaviorSubject');

观察

首先,我们来看看创建常规Observable的最小API。有几种方法可以创建Observable。创建Observable的方法是实例化类。其他操作符可以简化这个步骤,但我们希望将实例化步骤与不同的Observable类型进行比较

import { Observable } from 'rxjs';

const observable = new Observable(observer => {
  setTimeout(() => observer.next('hello from Observable!'), 1000);
});

observable.subscribe(v => console.log(v));

Observable对象表示一个基于推的集合。

观察者和可观察接口为基于推送的通知提供了一种通用机制,也称为观察者设计模式。Observable对象表示发送通知的对象(提供者);Observer对象表示接收它们的类(观察者)。

Subject类继承了Observable和Observer,也就是说它既是一个观察者又是一个可观察对象。您可以使用主题订阅所有观察者,然后将主题订阅到后端数据源

var subject = new Rx.Subject();

var subscription = subject.subscribe(
    function (x) { console.log('onNext: ' + x); },
    function (e) { console.log('onError: ' + e.message); },
    function () { console.log('onCompleted'); });

subject.onNext(1);
// => onNext: 1

subject.onNext(2);
// => onNext: 2

subject.onCompleted();
// => onCompleted

subscription.dispose();

更多信息https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/subjects.md

我认为可观察对象是主体的包装。而Observable仅用于订阅数据更改。Subject还可以用于将数据更改通知订阅者(使用next()方法)。下面是一个小的可观察的模式实现,它可能有助于您理解这个概念。打印稿操场