Javascript rxjs pausableBuffered多个订阅

Javascript rxjs pausableBuffered多个订阅,javascript,rxjs,Javascript,Rxjs,我正在尝试编写一个基于websocket rxjs的包装器 我正在努力理解rxjs 我有一个暂停流,它应该在发生错误时暂停可暂停的缓冲流,并在从websocket获得“ok”后恢复它们 不知何故,只有我的可暂停缓冲流上的第一个订阅被触发。从那时起,只有队列堆叠得更高 我准备了一个jsbin来复制这个问题 在这里,“msg received”流仅为第一次订阅触发。然后q和观测者开始叠加 我有一种感觉,这是关于冷热的观测结果,但我无法理解这些问题。我将感谢任何帮助 提前谢谢你 这不是冷/热问题。您

我正在尝试编写一个基于websocket rxjs的包装器

我正在努力理解rxjs

我有一个暂停流,它应该在发生错误时暂停可暂停的缓冲流,并在从websocket获得“ok”后恢复它们

不知何故,只有我的可暂停缓冲流上的第一个订阅被触发。从那时起,只有队列堆叠得更高

我准备了一个jsbin来复制这个问题

在这里,“msg received”流仅为第一次订阅触发。然后q和观测者开始叠加

我有一种感觉,这是关于冷热的观测结果,但我无法理解这些问题。我将感谢任何帮助


提前谢谢你

这不是冷/热问题。您在onMessage中所做的是订阅,然后处置。dispose终止序列。onMessageStream应该只订阅一次,例如,在构造函数中:

this.onmessageStream.subscribe(message => console.log('--- msg --- ', message.data));
应删除订阅块,包括dispose

另外,请注意,您使用的replaySubject没有计数,这意味着队列包含所有以前的值。除非这是所需的行为,否则请考虑将其更改为
.replaySubject(1)


这里有一个问题。

这不是冷/热问题。您在onMessage中所做的是订阅,然后处置。dispose终止序列。onMessageStream应该只订阅一次,例如,在构造函数中:

this.onmessageStream.subscribe(message => console.log('--- msg --- ', message.data));
应删除订阅块,包括dispose

另外,请注意,您使用的replaySubject没有计数,这意味着队列包含所有以前的值。除非这是所需的行为,否则请考虑将其更改为
.replaySubject(1)


这里有一个。

正如@Meir所指出的,subscribe块中的dispose是一个no-no,因为它的行为是不确定的。一般来说,我会避免使用
主题
,而是依赖工厂方法。您可以在此处看到重构版本:

这些变化的快速分解:

class WebSocketWrapper {
  // Inject the pauser from the external state
  constructor(pauser) {

    // Input you need to keep as a subject
    this.input$ = new Rx.Subject();

    // Create the socket
    this._socket = this._connect();      

    // Create a stream for the open event
    this.open$ = Rx.Observable.fromEvent(this._socket, 'open');

    // This concats the external pauser with the 
    // open event. The result is a pauser that won't unpause until
    // the socket is open.
    this.pauser$ = Rx.Observable.concat(
      this.open$.take(1).map(true)
      pauser || Rx.Observable.empty()
    )
      .startWith(false);

    // subscribe and buffer the input
    this.input$
      .pausableBuffered(this.pauser$)
      .subscribe(msg => this._socket.send(msg));

    // Create a stream around the message event
    this.message$ = Rx.Observable.fromEvent(this._socket, 'message')

      // Buffer the messages
      .pausableBuffered(this.pauser$)

      // Create a shared version of the stream and always replay the last
      // value to new subscribers
      .shareReplay(1);
  }

  send(request) {
    // Push to input
    this.input$.onNext(request);
  }

  _connect() {
    return new WebSocket('wss://echo.websocket.org');
  }
}

另外,您还应该避免依赖内部变量,如
source
,这些变量不用于外部消费。尽管RxJS 4相对稳定,但由于它们不是用于公共消费的,因此可以从您的下方将其更换。

正如@Meir所指出的,订阅块中的处置是不可接受的,因为其行为是不确定的。一般来说,我会避免使用
主题
,而是依赖工厂方法。您可以在此处看到重构版本:

这些变化的快速分解:

class WebSocketWrapper {
  // Inject the pauser from the external state
  constructor(pauser) {

    // Input you need to keep as a subject
    this.input$ = new Rx.Subject();

    // Create the socket
    this._socket = this._connect();      

    // Create a stream for the open event
    this.open$ = Rx.Observable.fromEvent(this._socket, 'open');

    // This concats the external pauser with the 
    // open event. The result is a pauser that won't unpause until
    // the socket is open.
    this.pauser$ = Rx.Observable.concat(
      this.open$.take(1).map(true)
      pauser || Rx.Observable.empty()
    )
      .startWith(false);

    // subscribe and buffer the input
    this.input$
      .pausableBuffered(this.pauser$)
      .subscribe(msg => this._socket.send(msg));

    // Create a stream around the message event
    this.message$ = Rx.Observable.fromEvent(this._socket, 'message')

      // Buffer the messages
      .pausableBuffered(this.pauser$)

      // Create a shared version of the stream and always replay the last
      // value to new subscribers
      .shareReplay(1);
  }

  send(request) {
    // Push to input
    this.input$.onNext(request);
  }

  _connect() {
    return new WebSocket('wss://echo.websocket.org');
  }
}

另外,您还应该避免依赖内部变量,如
source
,这些变量不用于外部消费。虽然RxJS 4相对稳定,但由于它们不是供公众使用的,所以可以从您的领导下进行更改。

我已经按照您的建议更改了代码!(非常感谢)现在我有另一个问题:在将obserables更改为“fromEvent”后,我不知道如何在断开和重新连接服务器时“替换”流(保持当前订阅服务器)。在我可以“重新绑定”我的私有函数并调用onNext发出事件之前,我已经按照你的建议更改了我的代码!(非常感谢)现在我有另一个问题:在将obserables更改为“fromEvent”后,我不知道如何在断开和重新连接服务器时“替换”流(保持当前订阅服务器)。在我可以“重新绑定”我的私有函数并调用onNext发出事件之前。