什么时候在rxjs中使用asObservable()?


84

我想知道的用途是什么asObservable

根据文档:

隐藏源序列身份的可观察序列。

但是,为什么需要隐藏序列?

Answers:


187

何时使用Subject.prototype.asObservable()

这样做的目的是防止主体的“观察者侧”泄漏出API。基本上,当您不希望人们能够“下一步”进入结果可观察对象时,可以防止泄漏抽象。

(注意:这实际上不是您应该如何将这样的数据源转换成Observable,而是应该使用new Observable构造函数,请参见下文)。

const myAPI = {
  getData: () => {
    const subject = new Subject();
    const source = new SomeWeirdDataSource();
    source.onMessage = (data) => subject.next({ type: 'message', data });
    source.onOtherMessage = (data) => subject.next({ type: 'othermessage', data });
    return subject.asObservable();
  }
};

现在,当某人从中获得可观察到的结果时,myAPI.getData()就无法next评估结果:

const result = myAPI.getData();
result.next('LOL hax!'); // throws an error because `next` doesn't exist

您通常应该使用new Observable()

在上面的示例中,我们可能正在创建我们本来不是想要的东西。首先,getData()它不像大多数可观察对象那样懒惰,它将立即创建基础数据源SomeWeirdDataSource(可能还有一些副作用)。这也意味着,如果您retryrepeat由此产生的可观察结果,它将无法像您认为的那样起作用。

最好将可创建的数据源封装在可观察的范围内,如下所示:

const myAPI = {
  getData: () => return new Observable(subscriber => {
    const source = new SomeWeirdDataSource();
    source.onMessage = (data) => subscriber.next({ type: 'message', data });
    source.onOtherMessage = (data) => subscriber.next({ type: 'othermessage', data });
    return () => {
      // Even better, now we can tear down the data source for cancellation!
      source.destroy();
    };
  });
}

使用上面的代码,可以使用RxJS的现有运算符在可观察的内容之上构成任何行为,包括使其“不懒惰”。


3
TX Ben ...一直在关注您的东西... TX对RX的所有强大支持
–born2net

3
@Shardul ...您将订阅结果:result.subscribe(value => doSomething(value))
Ben Lesh

2
@BenTaliadoros是的,每次您return subject.asObservable();都会看到一个新的变化。您只有一个Subject成员变量,并且onMessage / onOtherMessage将在条件或初始化时声明(并非每次调用都声明)。我已经使用了这种方法,并pipe( filter() )基于提供给getData()函数的参数。本
Drenai

5
@BenLesh,在您的第二个代码示例中subject应该是subscriber
Florin D

1
我在这里也想验证一下:subject.next线是否应该subscriber。另外,“如果重试或重复生成的可观察结果,它将无法像您认为的那样起作用。” 你可以说得更详细点吗?您是说new SomeWeirdDataSource()每次getData调用都会发生这种情况new Observable吗,并且通过将其包装在其中使实例化直到订阅为止。我想我看不到什么时候不打来电话getData.subscribe所以我错过了那里的价值。最后,您预计“拆除数据源”会发生什么?谢谢。
1252748

7

ASubject可以同时充当observerobservable

AnObervable有2种方法。

  • 订阅
  • 退订

每当您订阅observable,您都会获得,observer其上具有nexterrorcomplete方法。

您需要隐藏序列,因为您不希望在每个组件中公开流源。同样,您可以参考@BenLesh的示例。

PS:当我第一次使用Reactive Javascript时,我听不懂asObservable。因为我必须确保我清楚地了解基本知识,然后才去做asObservable。:)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.