Могу ли я использовать две карты слияния вместе в RxJS

#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, и если он возвращает наблюдаемое или обещание, то не используйте его.