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

依然范特西╮ 提交于 2019-12-10 16:38:07

问题


Context: I am working on implementing @ngrx/effects within an @ngrx/store project and studying the example app.

Question: In the BookEffects class file, line #50, why is takeUntil(...) used instead of take(1)? Both would seem to accomplish the same thing in this case.

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

And here is the 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());
  }
}

回答1:


To understand why takeUntil is used, it might help to make no assumptions about the implementation of searchBooks.

The searchBooks service method returns an observable of Book[]. That observable does not necessarily have to complete; for instance, it could emit additional results if the database changes (this is what happens with Firebase's AngularFire2 observables). However, if take(1) is used, subsequent results will be ignored. If takeUntil is used, subsequent results will continue to effect actions until the next search is initiated.

However, I don't think the takeUntil is essential, as the switchMap will take care of things (the inner observable will be unsubscribed, etc.).

The author(s) of the example-app appear to have implemented the search effect in such a way that it is not dependent upon the implementation of the service.

With the simple, Http-based implementation of searchBooks, I cannot see why either take(1) or takeUntil would be required - as the observable will complete and the switchMap will ensure that SearchCompleteAction actions for stale searches are not emitted.




回答2:


take(n) returns a specified number of contiguous elements from the start of an observable sequence

takeUntil(Observable | Promise) Returns the values from the source observable sequence until the other observable sequence or Promise produces a value.You should probably be using takeUntil to manage your RxJS subscriptions.

1) it fires a completion event when you kill your stream

2) fewer actual points of subscription (because fewer calls to subscribe)

for more info read this article https://medium.com/@benlesh/rxjs-dont-unsubscribe-6753ed4fda87#.ge4d447b6



来源:https://stackoverflow.com/questions/41657400/why-use-takeuntil-over-take1-with-http-service

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!