#ngrx 示例中的 SwitchMap 与 MergeMap [英] SwitchMap vs MergeMap in the #ngrx example

查看:29
本文介绍了#ngrx 示例中的 SwitchMap 与 MergeMap的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是 Ngrx 示例中的代码:

图中的第一行是源 Observable,它在不同时间发出 (1,3,5).图中的第二行是由 project 函数 i => 返回的原型 Observable... 传递给 .mergeMap() 操作符.

当源 Observable 发出项 1 时,mergeMap() 使用 i=1 调用 project 函数>.返回的 Observable 将发出 10 三次,每 10 帧(参见 这与 switchMap() 不同,它会在 project 返回的 Observable 中取消订阅,一旦它在新元素上再次调用它.大理石图通过输出 Observable 中缺少的第三个 30 项来表明这一点.

在您提供的示例中,这会导致取消待处理的搜索请求.这是一个非常好的但很难获得正确的属性,您可以通过将 switchMap() 与 Angular 的 Http<返回的可取消 Observables 结合来免费获得它/代码>服务.这可以为您省去很多麻烦,而无需担心正确处理异步取消通常会出现的所有竞争条件.

Below is code from the Ngrx example: https://github.com/ngrx/example-app/blob/master/src/effects/book.ts My question is why in the first @Effect, it uses switchMap while the others use mergeMap. Is that because the first @Effect is dealing with network, and with the switchMap you can cancel the previous network request if it's running?

@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)
      ))
    );
}

解决方案

You are correct; switchMap will unsubscribe from the Observable returned by its project argument as soon as it has invoked the project function again to produce a new Observable.

RxJs is incredibly powerful and dense, but its high level of abstraction can sometimes make code hard to understand. Let me debunk the marble diagrams and docs given by @Andy Hole a little and bring them up to date. You may find the marble syntax reference highly valuable to better understand rxjs operators from their tests (at least I found this missing/not highlighted enough in the official docs).

mergeMap

The first line in the diagram is the source Observable which emits (1,3,5) at different times. The second line in the diagram is the prototypical Observable returned by the project function i => ... passed to the .mergeMap() operator.

When the source Observable emits the item 1, mergeMap() invokes the project function with i=1. The returned Observable will emit 10 three times, every 10 frames (see marble syntax reference). The same happens when the source Observable emits item 3 and the project function creates an Observable that emits 30 three times. Note that the result of mergeMap() contains all three elements generated by each Observable returned from project.

switchMap

This is different with switchMap(), which will unsubscribe from the Observable returned by project as soon as it has invoked it again on a new element. The marble diagram indicates this with the missing third 30 item in the output Observable.

In the example you have given, this leads to the cancellation of the pending search request. This is a very nice but hard-to-get-right property, which you get for free by combining switchMap() with cancellable Observables returned by Angular's Http service. This can save you a lot of headaches without worrying about properly handling all the race conditions that typically occur with async cancellation.

这篇关于#ngrx 示例中的 SwitchMap 与 MergeMap的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆