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

Why use .takeUntil() over .take(1) with Http service?

上下文: 我正在努力实现 @ngrx/effects within an @ngrx/store project and studying the 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());
  }
}

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

takeUntil(Observable | Promise) Returns 来自源可观察序列的值,直到另一个可观察序列或 Promise 产生一个 value.You 可能应该是使用 takeUntil 来管理您的 RxJS 订阅。

1) 当您终止流时它会触发一个完成事件

2) 实际订阅点数较少(因为对subscribe的调用较少)

有关详细信息,请阅读本文 https://medium.com/@benlesh/rxjs-dont-unsubscribe-6753ed4fda87#.ge4d447b6

要理解为什么使用 takeUntil,不对 searchBooks 的实现做任何假设可能会有所帮助。

searchBooks 服务方法 returns Book[] 的一个可观察对象。该可观察对象不一定必须完成;例如,如果数据库发生变化,它可能会发出额外的结果(这就是 Firebase 的 AngularFire2 observables 发生的情况)。但是,如果使用 take(1),则后续结果将被忽略。如果使用takeUntil,则后续结果将继续影响操作,直到发起下一次搜索。

但是,我认为 takeUntil 不是必需的,因为 switchMap 会处理事情(内部可观察对象将被取消订阅等)。

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

使用简单的、基于 HttpsearchBooks 实现,我不明白为什么需要 take(1)takeUntil - 因为可观察对象将完成并且switchMap 将确保不会发出 SearchCompleteAction 过时搜索的操作。