Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
React native Redux Observables:具有多个事件的自定义观察者?_React Native_Rxjs_Phoenix Framework_Redux Observable - Fatal编程技术网

React native Redux Observables:具有多个事件的自定义观察者?

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

嗨,我正在尝试将redux observables与react native和一个称为Phoenix的websocket包装器一起使用,它基本上允许您在通过websocket接收某些消息时执行回调

以下是我尝试做的基本设置:

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标签