Вы правы, метод onSnapshot
не возвращает обещание. Вместо этого он возвращает функцию, которую можно использовать для отмены подписки на уведомления об изменениях. До тех пор, пока не будет вызвана эта функция отмены подписки, обратный вызов, переданный методу onSnapshot
, будет вызываться каждый раз при изменении документа. (документация указывает, что обратный вызов также будет вызываться немедленно с текущим содержание документа.)
Такие функции, как 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
. Как отказаться от подписки, зависит только от вашего варианта использования.
person
seniorquico
schedule
08.06.2019