使用Rx.Subject
创建Subject.create(observer, observable)
时,Subject
非常懒惰。当我尝试在没有订阅的情况下使用subject.onNext
时,它不会传递消息。如果我先subject.subscribe()
,我可以立即使用onNext
。
我们说我有一个Observer
,就像这样创建:
function createObserver(socket) {
return Observer.create(msg => {
socket.send(msg);
}, err => {
console.error(err);
}, () => {
socket.removeAllListeners();
socket.close();
});
}
然后,我创建了一个接受消息的Observable:
function createObservable(socket) {
return Observable.fromEvent(socket, 'message')
.map(msg => {
// Trim out unnecessary data for subscribers
delete msg.blobs;
// Deep freeze the message
Object.freeze(msg);
return msg;
})
.publish()
.refCount();
}
使用这两个功能创建主题。
observer = createObserver(socket);
observable = createObservable(socket);
subject = Subject.create(observer, observable);
通过此设置,我无法立即subject.onNext
(即使我不关心订阅)。这是设计的吗?什么是一个好的解决方法?
这些实际上是TCP套接字,这就是为什么我还没有依赖超级光滑的websocket主题。
答案 0 :(得分:3)
我认为您要做的就是使用ReplaySubject
作为观察者。
const { Observable, Subject, ReplaySubject } = Rx;
const replay = new ReplaySubject();
const observable = Observable.create(observer => {
replay.subscribe(observer);
});
const mySubject = Subject.create(replay, observable);
mySubject.onNext(1);
mySubject.onNext(2);
mySubject.onNext(3);
mySubject.subscribe(x => console.log(x));
mySubject.onNext(4);
mySubject.onNext(5);
结果:
1
2
3
4
5
...但如果你正在考虑做一个Socket实现,它会变得更加复杂。这是一个有效的套接字实现,但我不建议您使用它。相反,我建议你使用rxjs-dom中的一个社区支持的实现(如果你是RxJS 4或更低版本)或RxJS 5的一部分,两者都是我帮助过了。
function createSocketSubject(url) {
let replay = new ReplaySubject();
let socket;
const observable = Observable.create(observer => {
socket = new WebSocket(url);
socket.onmessage = (e) => {
observer.onNext(e);
};
socket.onerror = (e) => {
observer.onError(e);
};
socket.onclose = (e) => {
if (e.wasClean) {
observer.onCompleted();
} else {
observer.onError(e);
}
}
let sub;
socket.onopen = () => {
sub = replay.subscribe(x => socket.send(x));
};
return () => {
socket && socket.readyState === 1 && socket.close();
sub && sub.dispose();
}
});
return Subject.create(replay, observable);
}
const socket = createSocketSubject('ws://echo.websocket.org');
socket.onNext('one');
socket.onNext('two');
socket.subscribe(x => console.log('response: ' + x.data));
socket.onNext('three');
socket.onNext('four');