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

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

问题描述

以下是Ngrx示例中的代码: https: //github.com/ngrx/example-app/blob/master/src/effects/book.ts 我的问题是,为什么在第一个@Effect中,它使用switchMap,而其他人使用mergeMap.那是因为第一个@Effect正在处理网络,并且使用switchMap您可以取消先前的网络请求(如果正在运行)?

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

推荐答案

您是对的;一旦再次调用project函数以生成新的ObservableswitchMap将从其project参数返回的Observable退订.

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非常强大且密集,但是其高水平的抽象有时会使代码难以理解.让我对@Andy Hole提供的大理石图和文档进行一些揭穿,并使其保持最新.您可能会发现大理石语法参考非常有价值以便从他们的测试中更好地了解rxjs运算符(至少在官方文档中,我发现此缺失/未突出显示)

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).

图中的第一行是源Observable,它在不同的时间发出(1,3,5).图中的第二行是由project函数i => ...返回的原型Observable传递给.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.

当源Observable发出项1时,mergeMap()i=1调用project函数.返回的Observable将每10帧发出10三次(请参阅

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()不同,switchMap()会在新元素上再次调用project返回的Observable时退订.大理石图通过输出Observable中缺少的第三个30项指示了这一点.

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.

在您给出的示例中,这导致取消了待处理的搜索请求.这是一个非常好但很难获得的属性,您可以将switchMap()与Angular的Http服务返回的可取消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天全站免登陆