React native Redux Observables:具有多个事件的自定义观察者?
嗨,我正在尝试将redux observables与react native和一个称为Phoenix的websocket包装器一起使用,它基本上允许您在通过websocket接收某些消息时执行回调 以下是我尝试做的基本设置:React native Redux Observables:具有多个事件的自定义观察者?,react-native,rxjs,phoenix-framework,redux-observable,React Native,Rxjs,Phoenix Framework,Redux Observable,嗨,我正在尝试将redux observables与react native和一个称为Phoenix的websocket包装器一起使用,它基本上允许您在通过websocket接收某些消息时执行回调 以下是我尝试做的基本设置: import 'rxjs'; import { Observable } from 'rxjs'; import { Socket, Channel } from 'phoenix'; import * as channelActions from '../ducks/c
import 'rxjs';
import { Observable } from 'rxjs';
import { Socket, Channel } from 'phoenix';
import * as channelActions from '../ducks/channel';
export default function connectSocket(action$, store) {
return action$.ofType(channelActions.SETUP)
.mergeMap(action => {
return new Observable(observer => {
const socket = new Socket('http://localhost:4000/socket');
const userId = store.getState().user.id;
const channel = socket.channel(`user:${userId}`);
channel
.join()
.receive('ok', response => observer.next({ type: 'join', payload: 'something' }))
.receive('error', reason => observer.next({ type: 'error', payload: 'reason' }))
channel.on('rooms:add', room => observer.next({ type: 'rooms:add', payload: '123' }))
channel.on('something:else', room => observer.next({ type: 'something:else', payload: '123' }))
});
})
.map(action => {
switch (action.type) {
case 'join':
return channelActions.join(action.payload);
case 'error':
return channelActions.error(action.payload);
case 'rooms:add':
return channelActions.add(action.payload);
case 'something:else':
return channelActions.something(action.payload);
}
});
};
如您所见,这种方法存在几个问题:
.map()
函数中的switch语句之外,我不知道如何拆分它们observer.complete()
,因为我希望它继续侦听所有这些事件,而不是只侦听一次通道
常量提取到一个单独的文件中,该文件可供多个epics使用,从而解决这些问题。但是,频道
依赖于套接字
,后者依赖于来自redux状态的用户
通道对象的能力可以修复它,但这也取决于redux状态的用户ID。感谢您的帮助
另外,如果它有价值的话,我的用例与这个家伙非常相似()。其中一位响应者建议使用Rx.Subject
,但我不知道从哪里开始…看来你让你的生活变得格外困难。您已经映射了事件,为什么要合并并重新映射它们?将每个事件映射到自己的流中,并将结果合并在一起
// A little helper function to map your nonstandard receive
// function into its own stream
const receivePattern = (channel, signal, selector) =>
Observable.fromEventPattern(
h => channel.receive(signal, h),
h => {/*However you unsubscribe*/},
selector
)
export default function connectSocket(action$, store) {
return action$.ofType(channelActions.SETUP)
// Observable.create is usually a crutch pattern
// Use defer or using here instead as it is more semantic and handles
// most of the stream lifecycle for you
.mergeMap(action => Observable.defer(() => {
const socket = new Socket('http://localhost:4000/socket');
const userId = store.getState().user.id;
const channel = socket.channel(`user:${userId}`);
const joinedChannel = channel.join();
// Convert the ok message into a channel join
const ok = receivePattern(joinedChannel, 'ok')
// Just an example of doing some arbitrary mapping since you seem to be doing it
// in your example
.mapTo('something')
.map(channelActions.join);
// Convert the error message
const error = receivePattern(joinedChannel, 'error')
.map(channelActions.error);
// Since the listener methods follow a standard event emitter interface
// You can use fromEvent to capture them
// Rather than the more verbose fromEventPattern we used above
const addRooms = Observable.fromEvent(channel, 'rooms:add')
.map(channelActions.add);
const somethingElse = Observable.fromEvent(channel, 'something:else')
.map(channelActions.somethingElse);
// Merge the resulting stream into one
return Observable.merge(ok, error, addRooms, somethingElse);
});
);
};
更相关的RXJS,考虑添加RXJS,RX标签