当前位置: 首页 > 知识库问答 >
问题:

主体与行为主体在角度上[重复]

顾乐家
2023-03-14

我使用共享服务在2个独立组件之间传递数据。当我在共享服务中使用主题时,我无法在订阅组件的html中看到订阅的数据,但可以在订阅后在控制台中看到它。然而,如果我使用行为主题,它工作得很好。有人能解释一下原因吗?

sharedservice.ts:

  //code with subject (not working)
  private msgStatistics = new Subject<any>();
      msgStatistics$ = this.msgStatistics.asObservable();
      msgStats(message) {
        this.msgStatistics.next(message)
      } 


    //code with BehaviorSubject (working)
    private msgStatistics = new BehaviorSubject<Object>(null);
      msgStatistics$ = this.msgStatistics.asObservable();
      msgStats(message) {
        this.msgStatistics.next(message)
      }

组件2.ts:

this.shared_service.msgStatistics$.subscribe(res => {
        this.message = res
        console.log(this.message) 
})

上面的控制台在两种情况下都打印出消息的值,但是没有以html的形式呈现主题。

共有3个答案

翟青青
2023-03-14

只是补充一下这里的答案(都是正确的)。

主题-没有“记忆”它已经发出的东西。订阅的人将只接收从该点开始的发射。

ReplaySubject-具有X次发射的“内存”。订阅的人将在订阅后立即收到X个发射量。

BehaviorSubject - 本质上是一个重播主题,其“内存”为 1,但也具有“默认”值,即使您尚未调用 next,也会发出该值。

我提出这个问题的原因是因为你实际上是在寻找一个回放主题,而不是一个行为主题。在您的示例中,您正在执行以下操作:

private msgStatistics = new BehaviorSubject<Object>(null);

这是设置一个默认值为 null 的行为主体。如果有人在您下次呼叫之前订阅,他们实际上会收到 null 值。这可能不是你想要的,相反,你可能想做:

private msgStatistics = new ReplaySubject<Object>(1);

这样它仍然具有至少 1 次发射的内存,但没有您必须处理的 null 的“默认”值。

有关差异的更多信息,包括示例,可在此处找到:https://tutorialsforangular.com/2020/12/12/subject-vs-replaysubject-vs-behaviorsubject/

季阳朔
2023-03-14

这两个主题甚至在您订阅它之前就发出了值。但 BehaviorSubject 存储最后一个发出的值。因此,每当有东西订阅它时,它都会发出最后一个值。这就是我们创建一个具有初始值的行为主体的原因。

在代码new BehaviorSubject(null);中;,您正在将null指定为初始值

钱旻
2023-03-14

Subject 和 BehaviorSubject 之间的区别在于 BehaviorSubject保留最后一个值。任何新订阅者都将收到该值。

如果仅接收已订阅的订阅者发出的值,则使用主题。如果新订阅者到达,它将从方迟到并且什么也收不到。

你可以尝试一个简单的实验:

创建一个BehaviorSubject,并用一些已知的值初始化它。现在这些值已经存在,直到发出下一个值。

现在创建很少的订阅者。所有这些都将获得众所周知的价值。

对Subject执行同样的操作。您无法初始化它,因此在创建它后尝试发出一些东西。

然后创建订阅者,没有人会收到任何东西。

更新

我创建了一个小演示来展示差异。

一旦打开Stackblitz页面,您将看到两列[主题,行为主题]

打开控制台以查看输出。此时不存在订阅者。您可以更改要发出的值。然后单击“发出”什么都不会发生,只有调用该方法的日志语句。

示例输出:

onEmitSubject -> [value 4 subject]

onEmitBehaviorSubject -> [value 4 behavior subject]

现在真正的测试:

为主题和行为主题创建一个订阅者。

观察控制台,应该是这样的:

onCreateSubscriber4Subject

onCreateSubscriber4BehaviorSubject

BehaviorSubject Subscriber [0.03448180712702731] :: value: [value 4 behavior subject]

在这里你可以看到区别。一旦新订户到达BehaviorSubject,它将接收最后发出的值。对于主题,情况并非如此。不会为新订户发出以前发出的值。

Stackblitz公司

 类似资料:
  • 我一直在寻找了解这 3 个: 主题 行为主体 重播主题 我想使用它们,并知道何时、为什么使用它们,使用它们有什么好处,尽管我已经阅读了文档、观看了教程并搜索了谷歌,但我对此没有任何理解。 那么他们的目的是什么?一个真实的案例将是最受欢迎的,它甚至不需要编写代码。 我更喜欢一个干净的解释,而不仅仅是“a b = 非常感谢。

  • 我不清楚< code>Subject和< code>BehaviorSubject之间的区别。只是一个< code>BehaviorSubject有< code>getValue()函数吗?

  • 根据我的理解,是一个可以随时间变化的值(可以订阅,订阅者可以接收更新的结果)。这似乎与的目的完全相同。 何时使用与?使用比使用有好处吗?或者反之亦然?

  • 我试图测试mvcControllers注入UserPrincipal的访问: restPockMockMvc.perform(get(“/pocs”).principal(authToken)).andreturn();

  • 什么是 Subject? - RxJS Subject 是一种特殊类型的 Observable,它允许将值多播给多个观察者,所以 Subject 是多播的,而普通的 Observables 是单播的(每个已订阅的观察者都拥有 Observable 的独立执行)。 Subject 像是 Observable,但是可以多播给多个观察者。Subject 还像是 EventEmitters,维护着多个监听

  • 我正在使用以下版本 这是我的插件配置 在调试插件时,我看到分别发生的情况是:-当声明body为Pact converter假定主体是实例,因此它通过处的遍历方法。而且由于它以开头,因此不解析它。 我在https://github.com/brjt23/contract-to-pact/tree/master上发布了一个示例,以备需要更多关于我如何构建项目的信息。 我在定义groovy合同文件时做错