我如何使主题发射多次

时间:2019-04-21 21:52:38

标签: angular rxjs

这是我第一次尝试使套接字工作。

我的套接字服务基于此tutorial

基本上,整个过程归结为几个服务-WebsockServiceDashSocketService

下面是它们的代码:

import { Injectable } from '@angular/core';
import { Subject, Observable, Observer } from 'rxjs';

@Injectable()
export class WebsockService {

  constructor() {}
  private ws: WebSocket;

  private subject: Subject<MessageEvent>;

  public connect(url): Observable<MessageEvent>
  {
    if (this.subject)
    {
      this.ws.close();
    }
    this.subject = this.create(url);
    console.log('Successfully connected to: ' + url);
    return this.subject.asObservable()
  }

  public create(url): Subject<MessageEvent> 
  {
    this.ws = new WebSocket(url);

    let observable = Observable.create(
      (obs: Observer<MessageEvent>) => {
        this.ws.onmessage = obs.next.bind(obs);
        this.ws.onerror = obs.error.bind(obs);
        this.ws.onclose = obs.complete.bind(obs);

        return this.ws.close.bind(this.ws);
      }
    );

    let observer = {
      next: (data: Object) => {
        if (this.ws.readyState === WebSocket.OPEN)
        {
          this.ws.send(JSON.stringify(data));
        }
      }
    };
    return Subject.create(observer, observable);
  }
}

@Injectable()
export class DashSocketService {

  constructor( private wsService: WebsockService, private globals: Globals)
  {

  }

  public getDashInfoBySocket(filter_hash: string): Observable<Dash>
  {
    return this.wsService.connect(`${this.globals.WS_URL}/ws/channel/${filter_hash}`).pipe(
      map(
        res => {
          return new Dash().deserialize(JSON.parse(res.data));
        }
      )
    )
  }
}

我不确定代码是否编写正确,但是据我所知,我只能订阅一次此Observable。也就是说,如果稍后获得dash(类型为Observable),我只能以dash | async的方式使用它一次,其他尝试将不会返回任何结果。

所以我想知道如何像普通可观察对象一样使用此subject.asObservable()。

1 个答案:

答案 0 :(得分:0)

没有看到预订的代码,我不确定这是否是问题,但我会冒充地认为是...

问题不在于您可以订阅多少次,而是何时订阅。一切似乎都是一个主题,并且我假设服务也是如此。...因此,进行的任何订阅将在接收值之前等待下一次更新。基本上,所有订阅都必须在订阅之前进行。如果需要订阅者获取现有值,则需要通过BehaviorSubject过滤值。创建一个新的BehaviorSubject,然后订阅您现有的Observable,并且每次接收到新值时,将其推入您的行为主题。然后,让您的组件订阅BehaviorSubject(asObservable())。

希望这会有所帮助!