我能够使用正常的Firestore查询设置redux-observable
export const getStatementsEpic = (action$, store) => {
return action$.ofType(GET_STATEMENTS)
.filter(() => {
const state = store.getState()
return state.auth.user
})
.mergeMap(() => {
console.log('action', store.getState().auth.user.uid)
const db = firebase.firestore()
db.settings({ timestampsInSnapshots: true })
const query = db.collection('users')
.doc(store.getState().auth.user.uid)
.collection('statements')
.orderBy('uploadedOn', 'desc')
.limit(50)
return query.get().then(snapshot => {
console.log('Should have gotten snapshot')
return getStatementsSnapshot(snapshot)
})
})
}
但我想将其转换为实时,我尝试更改
return query.get().then(snapshot => {
到
return query.onSnapshot(snapshot => {
但它不起作用......我想这不是一个承诺?我该如何解决这个问题?
答案 0 :(得分:1)
您是正确的,onSnapshot
方法不会返回承诺。而是返回一个可用于从更改通知中取消订阅的功能。在调用该取消订阅功能之前,每次文档更改时都会调用传递给onSnapshot
方法的回调。 (documentation指示还将使用当前文档内容立即调用该回调。)
可以使用onSnapshot
函数将多次使用回调函数的函数fromEventPattern
转换为可观察的函数。 fromEventPattern
使用两个函数作为参数。您传递的第一个函数需要调用onSnapshot
,并将其传递给RxJS定义的处理程序作为回调。您传递的第二个函数需要调用onSnapshot
返回的取消订阅函数。当您订阅可观察对象(即在您的史诗中使用它)时,RxJS将调用第一个函数。取消订阅可观察对象时,RxJS将调用第二个函数。
以下是您的代码已更新为使用fromEventPattern
和新的RxJS管道的示例:
export const getStatementsEpic = (action$, state$) => action$.pipe(
ofType(GET_STATEMENTS),
withLatestFrom(state$),
filter(([action, state]) => state.auth.user),
mergeMap(([action, state]) => {
const db = firebase.firestore()
db.settings({ timestampsInSnapshots: true })
return fromEventPattern(
handler => db.collection('users')
.doc(state.auth.user.uid)
.collection('statements')
.orderBy('uploadedOn', 'desc')
.limit(50)
.onSnapshot(handler),
(handler, unsubscribe) => unsubscribe(),
).pipe(
map(getStatementsSnapshot),
takeUntil(action$.pipe(
ofType(STOP_GET_STATEMENTS),
)),
)
}),
)
请注意,我已将takeUntil
引入快照流。没有它(或类似的东西),快照流将永远不会结束。另一个可能的更改是使用switchMap
而不是mergeMap
。取消订阅的方式仅取决于您的用例。