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

RxJS配置可观察到的多播

能修谨
2023-03-14

我正在努力理解rxJs观察者/可观察的。

我有一个Angular应用程序,其中一个Inject table服务创建一个可观察的:

闲聊服务ts:

public chatObserver: Observer<any>;
public chatObservable: Observable<any>;
constructor() {
  this.chatObservable = Observable.create((observer: Observer<any>) => {
  this.chatObserver = observer;
  });
}

当聊天室中收到消息时。服务ts,消息(假定)是多播的:

this.chatObserver.next(chatMessage);

两个组件以这种方式订阅可观察对象:

constructor(private _chatService: ChatService) {}

ngOnInit() {
    this._chatService.chatObservable.subscribe(
      (message) => {
        console.log('New chat message received!', message)
        // Do something with message
      }
    );

问题:只有一个(最后一个订阅的)收到消息。

问:我如何配置可观察到多播到所有订阅者?

共有2个答案

上官高畅
2023-03-14

一个简单的复习。如果您想在订阅时(在服务/管道等中手动,或通过html模板中的异步管道)接收一些初始值/当前值,请使用行为主题。这里有一个关于你试图实现的目标的基本建议。当然,考虑到生产,还有很多事情要做。问候。

闲聊服务ts:

BackEndDB : ChatMessage[] = <Obtain data for chatHistory from your DB>();

如果您将任何后端存储用于聊天历史记录,请通过该源初始化BackEndDB,如果不是则将消息$设置为新行为主体

messages$ = new BehaviorSubject<ChatMessage[]> // (this.BackEndDB OR null);
sendMessage(message: ChatMessage): void {
  this.BackEndDB.push(message);
  this.messages$.next(this.BackEndDB);
}
getMessages(): Observable<ChatMessage[]> {
  return this.messages$.asObservable();
}

然后在组件中:

import {ChatService} from 'yourPath/chat.service'; 

@Component({ 
  selector: 'app-chat',
  templateUrl: ['./chat.component.html'],
  styleUrls: ['./chat.component.css'],
})
export class ChatComponent {
  inbox$: Observable<ChatMessage[]>;
  constructor(private chatService: ChatService) {
    this.inbox$ = this.chatService.getMessages(); 
  } 
  sendMessage(username, msg) {
    let message: ChatMessage = { 
      msg: msg, 
      sender: username 
    }
    this.chatService.sendMessage(message);
  }
} 

然后聊天。组成部分html:

<label> Your Name:  </label>
<input type="text" #userName>
<label> Your Message:  </label>
<input type="text" #userMessage>  
<button type="button" (click) = "sendMessage(userName.value,userMessage.value)">Send</button>
<div *ngIf="inbox$ | async; let messages ">
  <div *ngFor= "let message of messages ">
    <p> {{ message.sender  }} </p>
    <p> said: </p>
    <p> {{ message.msg }} </p>
  </div>
</div>

如果要重用ChatMessage接口,可以在共享文件夹中创建该接口,如果该接口仅在共享文件夹中使用,则可以直接在组件中创建:

interface ChatMessage {
  msg: string;
  sender: string;
}

我们将新消息推送到BackEndDB变量并调用Next的唯一原因是因为这是一个简单的演示。在现实中,您将使用FirestoreCollection Document.value更改()或任何其他实时数据服务。

魏鸿
2023-03-14

下面是一个如何使用多播观察者的示例:

//chat.service.ts:

public chatObserver: Subject<any>;
constructor() {
  this.chatObserver = new Subject();
}

发出聊天信息(受试者设计了nexterrorcomplete方法):

this.chatObserver.next(chatMessage);

在组件中订阅:

constructor(private _chatService: ChatService) {}

ngOnInit() {

  this._chatService.chatObserver.subscribe(
    (message) => {
      console.log('New chat message received!', message)
      // Do something with message
    }
  );

注意:但是当一些组件在发出聊天消息后订阅聊天观察者时,我建议使用行为主体而不是行为主体(只需将主体替换为行为主体)。

BehaviorSubject具有存储“当前”值的特性。这意味着您始终可以直接从BehaviorSubject(源/引号:https://medium.com/@luukgruijs/understanding-rxjs-behaviorsubject-replaysubject-and-asyncsubject-8cc061f1cfc0)

 类似资料:
  • 我对Observables和RxJs是新手,我想对回报进行调整。如果第一个选择器返回某个值,我希望第二个选择器可以观察到。但是如果第一个选择器没有返回那个特定的值,我想返回false,而不是(false)。我已经走了这么远,但这返回了一个可观察的结果

  • 我试图将一个角度函数转换为可观察模式,因为它的当前实现与它有一些异步性。为了讨论这个问题,我们举一个简单的例子。 可以通过以下方式将其转换为使用可观察对象: 我所面临的问题(据我所知)是针对无法访问内部选择语句的情况。 如果使用常规主题,订阅函数肯定不会得到任何值,因为事件的顺序是: 函数被调用 主题已创建 值已设置 调用函数订阅,因此仅在此事件发生后获取值 如果使用了BehaviorSubjec

  • 有人能向我解释一下为什么运算符可以接受返回或的函数吗? 官方文件说: FlatMap运算符通过将您指定的函数应用于源可观察对象发出的每个项目来转换可观察对象,其中该函数返回本身发出项目的可观察对象。 为什么它也可以返回数组? 例如,它们都是有效的: 但这不起作用:

  • 我已经阅读了ReactiveX留档几次,仍然无法完全理解当观察者订阅可观察文件时会发生什么。 我们来看一个简单的例子: StackBlitz代码。 我的问题: 传递给可观察对象的

  • 我试图理解当我使用 在或之后,在我使用时返回true 我知道是一次性的。isDisposed()返回false。有人能解释一下到底发生了什么吗?。我理解一个写得很好的观察。create不能在onComplete()或onError()之后发出项。

  • 因此,我有一个NgRx选择器,它返回一个带有一系列触点的可观测值。我想映射这个流,对于每个联系人数组,映射每个联系人,并向Github发出Http请求以获取他们的配置文件图像,并将其附加到联系人对象。然而,我不知道如何做到这一点,而不以一系列的可观测数据结束。 下面是我尝试过的,但这不起作用。 下面是我收到的错误消息: 如有任何建议,将不胜感激!