Redux Observable: как вернуть действие из обратного вызова?
Я использую библиотеку WebRTC, которая имеет очень специфический API. 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. Есть ли способ сделать это?
PS это API WebRTC: https://github.com/oney/react-native-webrtc/blob/master/RTCPeerConnection.js#L176
2 ответа
Так что проблема в том, что setRemoteSdp
не возвращает наблюдаемое время myReducer.myAction()
и это Обсерватория вы хотите объединить?
Ты можешь использовать Observable.create
и обернуть WebRTC.setRemoteSdp
вызов:
.mergeMap(action => {
return Observable.create(observer => {
WebRTC.setRemoteSdp(peerConnection, sdp, () => {
observer.next(myReducer.myAction());
observer.complete();
})
});
}
.mergeAll()
Observable.create
возвращает наблюдаемое, которое испускает другое наблюдаемое из myReducer.myAction()
, Теперь у меня есть так называемый высший порядок, который я хочу сгладить, используя mergeAll()
(concatAll
будет работать так же).
Ответ Мартина правильный об использовании Observable.create
или же new 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());
})
};
Вы можете использовать это для создания Observable оболочек для всех API WebRTC.