Lij*_*raj 20 javascript reactive-programming rxjs angular
我正在浏览这个博客并阅读有关Observables的内容,我无法弄清楚Observable与Subject之间的区别
jai*_*aji 103
Observable 设计为单播,Subjects 设计为多播。
如果您查看下面的示例 -每个订阅都会收到不同的值作为设计为单播开发的 observable。
import {Observable} from 'rxjs';
let obs = Observable.create(observer=>{
observer.next(Math.random());
})
obs.subscribe(res=>{
console.log('subscription a :', res); //subscription a :0.2859800202682865
});
obs.subscribe(res=>{
console.log('subscription b :', res); //subscription b :0.694302021731573
});
Run Code Online (Sandbox Code Playgroud)
如果您期望订阅的值相同,这可能会很奇怪。
我们可以使用 Subjects 来解决这个问题。主题类似于事件发射器,它不会为每个订阅调用。考虑下面的例子。
import {Subject} from 'rxjs';
let obs = new Subject();
obs.subscribe(res=>{
console.log('subscription a :', res); // subscription a : 0.91767565496093
});
obs.subscribe(res=>{
console.log('subscription b :', res);// subscription b : 0.91767565496093
});
obs.next(Math.random());
Run Code Online (Sandbox Code Playgroud)
两个订阅都获得了相同的输出值!。
Zah*_*hiC 31
在流编程中有两个主要接口:Observable和Observer.
Observable是针对消费者的,它可以被转换和订阅:
observable.map(x => ...).filter(x => ...).subscribe(x => ...)
Run Code Online (Sandbox Code Playgroud)
Observer是用于提供可观察源的接口:
observer.next(newItem)
Run Code Online (Sandbox Code Playgroud)
我们可以使用Observer创建新的Observable:
var observable = Observable.create(observer => {
observer.next('first');
observer.next('second');
...
});
observable.map(x => ...).filter(x => ...).subscribe(x => ...)
Run Code Online (Sandbox Code Playgroud)
或者,我们可以使用实现Observable和Observer接口的Subject:
var source = new Subject();
source.map(x => ...).filter(x => ...).subscribe(x => ...)
source.next('first')
source.next('second')
Run Code Online (Sandbox Code Playgroud)
小智 17
简要地,
subject:您可以向其发送并从中接收。
Observable:您只能从中接收。
换句话说,在主题中你可以订阅它,并且你可以使用它在代码中随时随地向其他订阅者广播。
而在observable中,您只能订阅它(初始化后不能使用它来广播数据)。唯一可以从 observable 广播数据的地方是在它的构造函数内部。
Mik*_*ton 11
我发现接受的答案有点令人困惑!
一个观察员 不用于喂养的接口可观察源,它是接口观察的可观察源...这使得从名字更有意义吧?
所以,原因是:
var observable = Observable.create(observer => {
observer.next('first');
observer.next('second');
...
});
Run Code Online (Sandbox Code Playgroud)
工作 - 创建一个发出“第一个”然后“第二个”的 observable - 的参数Observable.create(...)是subscribe 函数,它基本上定义了哪些Observer事件将在该Observable的直接Observer上发生。
如果你想再深入一点,重要的是要理解订阅函数在你订阅时不是直接在Observer对象上调用的,而是由一个Subscription对象中介,它可以强制执行正确的可观察规则,例如一个可观察绝不会发出一个新的值之后observer.complete()被调用,即使你的订阅功能,看起来好像会。
参考:http : //reactivex.io/rxjs/manual/overview.html#creating-observables
一个主题既是可观察和观测,并再次它看起来就像观察接口的方式,以“饲料”事件的主题。但是,如果您意识到Subject有点像Observable并具有与 subscribe 功能等效的Observable(即您定义观察它的事物将发生什么事件),则它更容易理解命名坐在对象上,即使在它之后已经被创造了。所以,你在Subject上调用Observer方法来定义什么Observer事件会发生在观察它的事物上!(同样,涉及中间对象,以确保您只能做合法的事情序列。)
参考:http : //reactivex.io/rxjs/manual/overview.html#subject
Joh*_*ith 10
请参阅rxjs文档(此处有更多信息和示例):http ://reactivex.io/rxjs/manual/overview.html#subject
什么是主题?RxJS主题是一种特殊的Observable类型,它允许将值多播到许多Observer。普通的Observable是单播的(每个订阅的Observer拥有Observable的独立执行),而Subject是多播的。
主题就像一个可观察对象,但是可以多播到许多观察者。主题就像EventEmitters:它们维护着许多侦听器的注册表。
和代码,Subject扩展Observable如下:https : //github.com/ReactiveX/rxjs/blob/master/src/internal/Subject.ts#L22
/**
* @class Subject<T>
*/
export class Subject<T> extends Observable<T> implements SubscriptionLike {
//...
}
Run Code Online (Sandbox Code Playgroud)
小智 8
可观察的
它们很冷:只有至少一个观察者时,代码才能执行。
创建数据副本:Observable为每个观察者创建数据副本。
单向:观察者无法将值分配给可观察(原始/主)。
该代码将为每个观察者运行。如果是HTTP调用,则会为每个观察者调用。
如果它是我们希望在所有组件之间共享的服务,它将不会有最新的结果,所有新订户仍将订阅相同的可观察的内容并从头开始获得价值
单播装置可以从可观察到的而不是从任何其他组件发出值。
学科
它们很热:即使没有观察者,代码也会被执行,价值也会得到传播。
共享数据:在所有观察者之间共享相同的数据。
双向:观察者可以将值分配给可观察(原始/主)。
如果正在使用主题,则您会错过创建观察者之前广播的所有值。所以这是重播主题
multicast, can cast values to multiple subscribers and can act as both subscribers and emmitter
从另一个角度来看,注意到订阅一个 Observable 会重新执行 Observable 函数是好的。例如,如果数据源是服务,这可能会导致性能问题。
如果您希望多个订阅者获得相同的值,您可能需要一个 Subject。为此,请确保在主题订阅数据源之前设置您的订阅。否则,您的过程将被卡住。
更多细节在这里:https : //javascript.tutorialhorizon.com/2017/03/23/rxjs-subject-vs-observable/
想象一下,如果您有一个数据流进入您的应用程序,就像在 websocket 连接中一样。你想要一种方法来处理它。有几个解决办法:
1.普通ajax请求: 这个方案不可行,因为不适用于处理推送数据。与其说是推,不如说是拉。
2. Promise: 也不好,因为你必须触发它们并且它们只能检索一次。也更多的是拉然后推。
所以为了取回这些数据,在过去,我们做一个长轮询。例如,我们在这里设置了一个间隔函数来每 1 分钟检索一次该数据流。虽然它有效,但它实际上加重了 CPU 和内存等资源的负担。
但现在有了选项 3,
3. Observable:你可以订阅并让数据流不停地进来,直到函数完成被调用。
酷吧?但是还有另一个问题。如果您只想在应用程序中的某处观察一次传入数据,该怎么办?但是您希望在数据到达时在您的应用程序周围同时使用该数据。那是您何时何地使用主题。您将 subject.subscribe() 放在要在整个应用程序中使用的地方。当数据到达时,有subject.subscribe() 的地方会同时处理它们。但是观察者必须像这样订阅主题作为其参数。
观察者.订阅(主题)。
示例应用程序是当您想要构建通知警报时。
您不能对同一个 observable 进行多个订阅,因为很有可能每个订阅者都会收到不同的输入数据。但是对于主题,所有通过主题 subscribe() 的操作都将检索相同的数据。
另一个类比是通过杂志订阅。每个订阅者都会收到带有他们名字的杂志。所以,不同的订阅 = 不同的接收者姓名。(Normal Observable)但是当你与你的朋友分享时,你所有的朋友都会收到同样的杂志,上面只有你的名字。(Normal Observable with Subject)
这家伙用代码示例很好地解释了它。您可以在https://javascript.tutorialhorizon.com/2017/03/23/rxjs-subject-vs-observable/查看
希望这个答案有帮助。
Observable:只有 Observable 知道事件如何以及何时在 observable 上触发。即该next()方法只能在实例化的构造函数内部调用。此外,每次订阅时,都会创建一个单独的观察者,并next()仅使用构造函数内的特定观察者调用方法,在下面的示例中,subscriber它本身就是观察者,并且在执行实例化构造函数时会订阅它。前任:
import { Observable } from 'rxjs';
const observable = new Observable(subscriber => {
subscriber.next(1);
subscriber.next(2);
setTimeout(() => {
subscriber.next(3);
}, 1000);
});
Run Code Online (Sandbox Code Playgroud)
主体:next()主体可以在构造函数之外的任何地方使用此方法。此外,当next()在订阅之前调用方法时,将错过特定事件。因此,next()只有在订阅后才必须调用该方法。前任:
import { Subject } from 'rxjs';
const subject = new Subject<number>();
subject.next(1); // this is missed
subject.subscribe({
next: (v) => console.log(`observerA: ${v}`)
});
subject.subscribe({
next: (v) => console.log(`observerB: ${v}`)
});
subject.next(2);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8733 次 |
| 最近记录: |