简体   繁体   中英

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

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

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM