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