SwitchMap против MergeMap в примере #ngrx

Ниже приведен код из примера Ngrx: https://github.com/ngrx/example-app/blob/master/src/effects/book.ts Мой вопрос заключается в том, почему в первом @Effect он использует switchMap в то время как другие используют mergeMap, Это потому, что первый @Effect имеет дело с сетью, а с switchMap Вы можете отменить предыдущий сетевой запрос, если он запущен?

@Effect() search$ = this.updates$
    .whenAction(BookActions.SEARCH)
    .map<string>(toPayload)
    .filter(query => query !== '')
    .switchMap(query => this.googleBooks.searchBooks(query)
      .map(books => this.bookActions.searchComplete(books))
      .catch(() => Observable.of(this.bookActions.searchComplete([])))
    );


  @Effect() clearSearch$ = this.updates$
    .whenAction(BookActions.SEARCH)
    .map<string>(toPayload)
    .filter(query => query === '')
    .mapTo(this.bookActions.searchComplete([]));


  @Effect() addBookToCollection$ = this.updates$
    .whenAction(BookActions.ADD_TO_COLLECTION)
    .map<Book>(toPayload)
    .mergeMap(book => this.db.insert('books', [ book ])
      .mapTo(this.bookActions.addToCollectionSuccess(book))
      .catch(() => Observable.of(
        this.bookActions.addToCollectionFail(book)
      ))
    );


  @Effect() removeBookFromCollection$ = this.updates$
    .whenAction(BookActions.REMOVE_FROM_COLLECTION)
    .map<Book>(toPayload)
    .mergeMap(book => this.db.executeWrite('books', 'delete', [ book.id ])
      .mapTo(this.bookActions.removeFromCollectionSuccess(book))
      .catch(() => Observable.of(
        this.bookActions.removeFromCollectionFail(book)
      ))
    );
}

6 ответов

Ты прав; switchMap отписаться от Observable вернулся его project аргумент, как только он вызвал project функционировать снова, чтобы произвести новый Observable,

RxJs невероятно мощный и плотный, но его высокий уровень абстракции иногда может затруднить понимание кода. Позвольте мне немного разоблачить мраморные схемы и документы, данные @Andy Hole, и привести их в соответствие. Вы можете найти мраморную ссылку на синтаксис очень полезной для лучшего понимания операторов rxjs из их тестов (по крайней мере, я обнаружил, что это отсутствует / недостаточно выделено в официальных документах).

mergeMap

mergeMap

Первая строка на диаграмме - это источник Observable, который испускает (1,3,5) в разное время. Вторая строка на диаграмме является прототипом Observable, возвращаемым project функция i => ... перешел к .mergeMap() оператор.

Когда источник Observable испускает элемент 1, mergeMap() вызывает project функция с i=1, Возвращенный Observable будет излучать 10 три раза каждые 10 кадров (см. справочник по синтаксису мрамора). То же самое происходит, когда источник Observable испускает элемент 3 и project Функция создает Observable, который испускает 30 три раза. Обратите внимание, что результат mergeMap() содержит все три элемента, сгенерированные каждым Observable, возвращаемым из project,

switchMap

switchMap Это отличается от switchMap(), который будет отписываться от Observable возвращается project как только он снова вызовет его для нового элемента. Мраморная диаграмма показывает это с отсутствующей третьей 30 пункт в выводе Observable.

В приведенном вами примере это приводит к отмене ожидающего поискового запроса. Это очень хороший, но трудно получить право собственности, которую вы получаете бесплатно, комбинируя switchMap() с отменяемыми Observables, возвращенными Angular's Http оказание услуг. Это может избавить вас от многих головных болей, не беспокоясь о правильной обработке всех условий гонки, которые обычно возникают при асинхронном аннулировании.

Его уже ответили и очень подробно, но посмотрите на это, и вы никогда не забудете, что такое switchmap

https://www.youtube.com/watch?v=rUZ9CjcaCEw

Вы правы.

Как видите, switchMap используется с функцией поиска. Поле поиска в этом примере запрограммировано на генерацию запроса поиска, когда пользователь вводит текст в текстовое поле (с задержкой или задержкой 350 мс).

Это означает, что когда пользователь вводит 'har', ngrx отправляет поисковый запрос в службу. Когда пользователь вводит другую букву "r", предыдущий запрос отменяется (поскольку нас больше не интересует "har", а "harr").

Это очень хорошо показано на мраморных диаграммах, приведенных в другом ответе. В mergeMap предыдущие Observables не отменяются, и поэтому "30" и "50" смешиваются вместе. При использовании switchMap испускаются только 5, потому что 3 отменяются.

mergeMap

Проецирует каждое исходное значение в Observable, который объединяется в выходной Observable.

Отображает каждое значение в Observable, а затем выравнивает все эти внутренние Observable, используя mergeAll.

switchMap

Проецирует каждое исходное значение в Observable, которое объединяется в выходной Observable, испуская значения только из самых последних прогнозируемых Observable.

Отображает каждое значение в Observable, а затем выравнивает все эти внутренние Observable, используя переключатель.

Источник: ES6 Observables в RxJS

Да, если вас больше не интересует ответ на предыдущий запрос при поступлении нового ввода, switchMap является подходящим оператором, а не mergeMap.

Вы не хотите, чтобы запрос данных сохранения API отменялся. Вот почему вы должны использовать mergeMap. Поисковый запрос может быть отброшен без потери данных, и пользователь может редактировать свой запрос и не интересоваться данными для старого запроса. Следовательно, switchMap.

Другие вопросы по тегам