Angular 中的Subject 与BehaviorSubject

bha*_*sri 1 subject-observer behaviorsubject angular

我使用共享服务在两个独立组件之间传递数据。当我在共享服务中使用主题时,我无法在订阅组件的html中看到订阅的数据,但订阅后可以在控制台中看到它。而如果我使用Behaviorsubject,效果很好。谁能给我解释一下原因。

共享服务.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)
      }
Run Code Online (Sandbox Code Playgroud)

组件2.ts:

this.shared_service.msgStatistics$.subscribe(res => {
        this.message = res
        console.log(this.message) 
})
Run Code Online (Sandbox Code Playgroud)

上面的控制台在这两种情况下都会打印消息的值,但它不会以 html 形式呈现主题。

rob*_*ert 5

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

如果Subject只有那些已经订阅的订阅者才会收到发出的值。如果有新订阅者到达,它将不会late from the party收到任何信息。

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

创建一个BehaviorSubject并用一些众所周知的值初始化它。现在该值一直存在,直到发出下一个值为止。

现在创建几个订阅者。他们所有人都将获得众所周知的价值。

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

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

更新

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

打开 Stackblitz 页面后,您将看到两列 [Subject、BehaviourSubject]

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

示例输出:

onEmitSubject -> [value 4 subject]

onEmitBehaviorSubject -> [value 4 behavior subject]
Run Code Online (Sandbox Code Playgroud)

现在真正的测试:

为Subject 和BehaviorSubject 创建一个订阅者。

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

onCreateSubscriber4Subject

onCreateSubscriber4BehaviorSubject

BehaviorSubject Subscriber [0.03448180712702731] :: value: [value 4 behavior subject]
Run Code Online (Sandbox Code Playgroud)

在这里你可以看到差异。一旦新订阅者到达,BehaviorSubject它就会收到最后发出的值。Subject事实并非如此。之前发出的值将不会为新订阅者发出。

斯塔克闪电战