链接观察者 RxJs

时间:2021-04-14 20:14:43

标签: typescript rxjs observable

我正在使用 Observables 在我的 Angular 程序中实现 WebSocket 服务。到目前为止,我有

    readwrite(commands: command[]) : Observable<response[]>{
        const observabe = new Observable((observer)=>{
            this.socket.subscribe((socket:WebSocket)=>{
                const id = this.uid++;
                //// Not Sure About This ////
                this.observerMap[id]={
                    next: next=>{
                        observer.next(next);
                        delete this.observerMap[id]; ////<---- What I want to Achieve
                    },
                    error: error=> observer.error(error),
                    complete: ()=>observer.complete()
                }
                socket.send(JSON.stringify({requestType:'ReadWrite', commands: commands, id: id}));
            });
        });
        return observable;
    }

然后在我的 ws.onmessgae 中我有

    {
        const result = JSON.parse(event.data);
        this.observerMap[result.id]?.next(result.commands);
    }

这似乎是我想要的,但我不确定是否有更干净的方法来处理这个问题。我无法清理 observableMap[] 中的 ws.onmessage,因为其他消息在多条消息中持有一个观察者。我也只想在 Observable 的 .next() 被处理后进行清理,这导致我找到了这个解决方案。使用 .pipe() 会导致在观察者执行之前执行。

是否有更简洁的方法将这些操作链接在一起?

2 个答案:

答案 0 :(得分:1)

我认为您应该通过以下方式使用完整的功能:

readwrite(commands: command[]) : Observable<response[]>{
    const observabe = new Observable((observer)=>{
        this.socket.subscribe((socket:WebSocket)=>{
            const id = this.uid++;
            this.observerMap[id]={
                next: next=>{
                    observer.next(next);
                },
                error: error=> observer.error(error),
                complete: ()=> { 
                   observer.complete()
                   delete this.observerMap[id];
                }
            }
            socket.send(JSON.stringify({requestType:'ReadWrite', commands: commands, id: id}));
        });
    });
    return observable;
}

然后在 onmessage 中:

{
    const result = JSON.parse(event.data);
    this.observerMap[result.id]?.next(result.commands);
    this.observerMap[result.id]?.complete();
}

答案 1 :(得分:0)

Subject 是一个完美的用例。您编写 observerMap 的方式实际上是实现一个主题。使用起来非常简单。

  1. 在您想要的服务中声明您的主题:
export class MessageService {

    message$ = new Subject<any>;
    constructor() { }
  }
  1. 在需要 onmessage 的代码中,每次收到新消息时只需执行 .next()
  {
        const result = JSON.parse(event.data);
        this.messageService.message$.next(result.commands);
  }
  1. 在你的组件中订阅它:
{
    this.messageService.message$.subsrcibe(console.log)
}