为什么在Http服务上使用.takeUntil()而不是.take(1)?

时间:2017-01-15 03:06:51

标签: angular rxjs ngrx

背景信息:我正在@ngrx/effects项目中实施@ngrx/store并研究example app

问题:在BookEffects class file第50行,为什么使用takeUntil(...)代替take(1)?在这种情况下,两者似乎都会完成同样的事情。

@Injectable()
export class BookEffects {
  constructor(private actions$: Actions, private googleBooks: GoogleBooksService) { }

  @Effect()
  search$: Observable<Action> = this.actions$
    .ofType(book.ActionTypes.SEARCH)
    .debounceTime(300)
    .map((action: book.SearchAction) => action.payload)
    .switchMap(query => {
      if (query === '') {
        return empty();
      }

      const nextSearch$ = this.actions$.ofType(book.ActionTypes.SEARCH).skip(1);

      return this.googleBooks.searchBooks(query)
        .takeUntil(nextSearch$)
        .map(books => new book.SearchCompleteAction(books))
        .catch(() => of(new book.SearchCompleteAction([])));
    });
}

这是Google Books service file

@Injectable()
export class GoogleBooksService {
  private API_PATH: string = 'https://www.googleapis.com/books/v1/volumes';

  constructor(private http: Http) {}

  searchBooks(queryTitle: string): Observable<Book[]> {
    return this.http.get(`${this.API_PATH}?q=${queryTitle}`)
      .map(res => res.json().items || []);
  }

  retrieveBook(volumeId: string): Observable<Book> {
    return this.http.get(`${this.API_PATH}/${volumeId}`)
      .map(res => res.json());
  }
}

2 个答案:

答案 0 :(得分:4)

要了解使用takeUntil的原因,可能有助于对searchBooks的实施做出任何假设。

searchBooks服务方法返回Book[]的可观察量。这种可观察性并不一定要完成;例如,如果数据库发生变化,它可能会发出额外的结果(这就是Firebase的AngularFire2 observable所发生的情况)。但是,如果使用take(1),则后续结果将被忽略。如果使用takeUntil,则后续结果将继续执行操作,直到启动下一次搜索。

然而,我并不认为takeUntil是必不可少的,因为switchMap会照顾事物(内部可观察者将被取消订阅等)。

example-app的作者似乎已经以不依赖于服务实现的方式实现了搜索效果。

使用基于Http的简单searchBooks实现,我无法理解为什么需要take(1)takeUntil - 因为observable将完成,{ {1}}将确保不会发出针对陈旧搜索的switchMap操作。

答案 1 :(得分:-1)

take(n)从可观察序列的开头返回指定数量的连续元素

takeUntil(Observable | Promise)返回源可观察序列中的值,直到其他可观察序列或Promise产生值。您应该使用takeUntil来管理RxJS订阅

1)当你杀了你的流时它会触发一个完成事件

2)更少的实际订阅点(因为对subscribe的呼叫次数减少)

了解更多信息,请阅读本文https://medium.com/@benlesh/rxjs-dont-unsubscribe-6753ed4fda87#.ge4d447b6