【问题标题】:Redux Observable: How to return an action from a callback?Redux Observable:如何从回调中返回一个动作?
【发布时间】:2017-10-07 07:57:51
【问题描述】:

我正在使用具有非常特定 API 的 WebRTC 库。 peerConnection.setRemoteDescription 方法的第二个参数应该是完成设置远程描述时的回调:

这是我的 WebRTC 类的包装函数之一:

export function setRemoteSdp(peerConnection, sdp, callback) {
  if (!sdp) return;
  return peerConnection.setRemoteDescription(
    new RTCSessionDescription(sdp),
    callback, // <-------------
  );
}

这是我想做的事情的草图:

function receivedSdp(action$, store) {
  return action$.ofType(VideoStream.RECEIVED_SDP)
    .mergeMap(action => {
      const {peerConnection} = store.getState().videoStreams;
      const {sdp} = action.payload;

      return WebRTC.setRemoteSdp(peerConnection, sdp, () => {
        return myReducer.myAction(); // <------ return action as the callback
      })
    })
};

这不起作用,因为我没有返回 Observable。有没有办法做到这一点?

附:这是 WebRTC API:https://github.com/oney/react-native-webrtc/blob/master/RTCPeerConnection.js#L176

【问题讨论】:

    标签: rxjs redux-observable


    【解决方案1】:

    关于使用Observable.createnew Observable,马丁的回答是正确的——同样的事情(除了我不清楚为什么你需要mergeAll(),因为mergeMap 会变平?)

    作为奖励,您还可以为此使用Observable.bindCallback

    // bindCallback is a factory factory, it creates a function that
    // when called with any arguments will return an Observable that
    // wraps setRemoteSdp, handling the callback portion for you.
    // I'm using setRemoteSdp.bind(WebRTC) because I don't know
    // if setRemoteSdp requires its calling context to be WebRTC
    // so it's "just in case". It might not be needed.
    const setRemoteSdpObservable = Observable.bindCallback(WebRTC.setRemoteSdp.bind(WebRTC));
    
    setRemoteSdpObservable(peerConnection, sdp)
      .subscribe(d => console.log(d));
    

    你的史诗中的用法是这样的

    // observables are lazy, so defining this outside of our epic
    // is totally cool--it only sets up the factory
    const setRemoteSdpObservable = Observable.bindCallback(WebRTC.setRemoteSdp.bind(WebRTC));
    
    function receivedSdp(action$, store) {
      return action$.ofType(VideoStream.RECEIVED_SDP)
        .mergeMap(action => {
          const {peerConnection} = store.getState().videoStreams;
          const {sdp} = action.payload;
    
          return setRemoteSdpObservable(peerConnection)
            .map(result => myReducer.myAction());
        })
    };
    

    您可以使用它为所有 WebRTC api 创建 Observable 包装器。

    【讨论】:

      【解决方案2】:

      所以问题是 setRemoteSdp 没有返回 Observable 而 myReducer.myAction() 确实返回了你想要合并的 Observable?

      您可以使用Observable.create 并包装WebRTC.setRemoteSdp 调用:

      .mergeMap(action => {
        return Observable.create(observer => {
          WebRTC.setRemoteSdp(peerConnection, sdp, () => {
            observer.next(myReducer.myAction());
            observer.complete();
          })
        });
      }
      .mergeAll()
      

      Observable.create 返回一个 Observable,它从 myReducer.myAction() 发出另一个 Observable。现在我实际上有所谓的高阶,我想使用mergeAll() 进行展平(concatAll 也可以)。

      【讨论】:

      • 天才! Observable.create 是我一直在寻找的。谢谢马丁
      • @martin hmm 为什么需要mergeAllmergeMap 将展平返回的自定义 Observable,它只发出 POJO 操作?
      猜你喜欢
      • 2017-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-07
      • 2021-12-20
      • 2021-02-05
      • 2017-08-25
      相关资源
      最近更新 更多