#javascript #typescript #react-native #rxjs
Вопрос:
Я начал использовать RxJS с redux, и я создал поток, который работает. Вот моя трубка для действий:
action$.pipe(
ofType(DELETE_CALL_HISTORY),
withLatestFrom(state$),
mergeMap(() =>
fromPromise(accessService.getCallHistory()).pipe(
mergeMap((res: any) => of(deleteCallHistory(res))),
mergeMap((res: any) => of(setCallHistory(res.param))),
catchError((err: any) => {
console.error(err);
return of(
showErrorAndHideAfterDelay({
message: err,
label: 'Error',
}),
);
}),
),
),
),
Здесь я пытался использовать три действия. getCallHistory
действие заключается в том, чтобы сначала получить данные. deleteCallHistory
действие заключается в удалении элемента из списка. Труба действия работает до сих пор. После этого я пытаюсь настроить обновленный список с помощью действия setCallHistory
. Но это не работает. Вызывается действие setCallHistory, но когда я перезагружаю приложение, удаленные элементы возвращаются. Должен ли я использовать mergeMap
это дважды или мне нужно использовать что-то еще?
Комментарии:
1. Откуда
getCallHistory
берутся данные? тебяsetCallHistory
вызывают? Это на самом деле сохранение измененных данных в источнике?
Ответ №1:
Примечание к вашему коду:
// ...
mergeMap((res: any) => of(deleteCallHistory(res))),
// now pipeline contains response of the deleteCallHistory
mergeMap((res: any) => of(setCallHistory(res.param))),
//...
Вы не забыли обернуть вызовы API fromPromise
?:
// ...
mergeMap((res: any) => fromPromise(deleteCallHistory(res))),
// now pipeline contains response of the deleteCallHistory
mergeMap((res: any) => fromPromise(setCallHistory(res.param))),
//...
Для последовательного выполнения N вызовов API используйте concat
:
import { concat } from 'rxjs';
// ...
mergeMap((res: any) => concat(
of(deleteCallHistory(res))),
of(setCallHistory(res.param))),
),
//...
Для параллельного выполнения N вызовов API используйте merge
:
import { merge } from 'rxjs';
// ...
mergeMap((res: any) => merge(
of(deleteCallHistory(res))),
of(setCallHistory(res.param))),
),
//...
Ответ №2:
Почему вы вызываете mergeMap и используете его внутри?
Следующее очень близко к тому, чтобы быть эквивалентным:
mergeMap((res: any) => of(deleteCallHistory(res)))
map((res: any) => deleteCallHistory(res)))
Они оба передадут результат deleteCallHistory в потоке. Ошибка, скорее всего, здесь. Если deleteCallHistory возвращает наблюдаемое, то это наблюдаемое никогда не будет выполнено, поскольку результатом является наблюдаемое, завернутое в наблюдаемое по.
Итак, если deleteCallHistory возвращает обещание или наблюдаемое, вы можете просто вызвать mergeMap, не оборачивая deleteCallHistory во что-либо:
mergeMap((res: any) => deleteCallHistory(res))
Это также может быть проблемой при вызове setCallHistory. Если вам не нужно передавать результат, вы можете использовать tap или do, и если он возвращает наблюдаемое или обещание, то не используйте его.