在#ngrx示例中,SwitchMap与MergeMap相对应

Tuo*_* Le 53 rxjs 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)
      ))
    );
}
Run Code Online (Sandbox Code Playgroud)

Joh*_*lph 83

你是对的; 只要再次调用该函数生成新函数,switchMap它将取消订阅Observableproject参数返回的内容.projectObservable

RxJs非常强大且密集,但其高级抽象有时会使代码难以理解.让我揭穿@Andy Hole给出的大理石图表和文档,并让它们更新.你可能会发现大理石语法参考非常有价值,可以更好地从他们的测试中理解rxjs操作符(至少我发现这个缺失/在官方文档中没有突出显示).

mergeMap

mergeMap

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

当源Observable发出该项时1,mergeMap()调用该project函数i=1.返回的Observable将10每10帧发出三次(参见大理石语法参考).当源Observable发出项3并且该project函数创建一个发出30三次的Observable 时,也会发生同样的情况.请注意,结果mergeMap()包含由返回的每个Observable生成的所有三个元素project.

switchMap

switchMap 这是不同的switchMap(),project一旦它在新元素上再次调用它,它将取消订阅Observable .大理石图表显示30了输出Observable中缺少的第三个项目.

在您给出的示例中,这会导致取消挂起的搜索请求.这是一个非常好但很难获得的属性,你可以通过结合switchMap()Angular Http服务返回的可取消的Observable 来免费获得.这可以为您节省很多麻烦,而无需担心正确处理通常在异步取消时发生的所有竞争条件.


Sur*_*gar 10

它的答案已经非常详细,但是请仔细阅读,您将永远不会忘记什么是switchmap

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

  • 那真是太好笑了,让我开心了。谢谢 (2认同)

Ale*_*ski 7

你是对的.

如您所见,switchMap与搜索功能一起使用.该示例中的搜索框被编程为当用户在文本框中输入文本时(具有350ms去抖或延迟)基本上发出搜索请求.

这意味着当用户输入'har'时,ngrx会向服务发送搜索请求.当用户输入另一个字母'r'时,先前的请求被取消(因为我们不再对'har'感兴趣,而是'harr').

它在另一个答案中提供的大理石图中非常精美地显示出来.在mergeMap中,之前的Observables没有被取消,因此"30"和"50"混合在一起.使用switchMap,只会发出5s,因为3会被取消.


小智 5

mergeMap

将每个源值投影到Observable,该Observable在输出Observable中合并.

将每个值映射到Observable,然后使用mergeAll展平所有这些内部Observable.

在此输入图像描述

switchMap

将每个源值投影到一个Observable,该Observable在输出Observable中合并,仅从最近投影的Observable中发出值.

将每个值映射到Observable,然后使用switch展平所有这些内部Observable.

在此输入图像描述

资料来源:RxJS中的ES6 Observables

  • 我不是在寻找mergeMap和switchMap的定义 (10认同)