为什么在 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
的作者似乎以不依赖于服务实现的方式实现了搜索效果。
使用简单的、基于 Http
的 searchBooks
实现,我不明白为什么需要 take(1)
或 takeUntil
- 因为可观察对象将完成并且switchMap
将确保不会发出 SearchCompleteAction
过时搜索的操作。
上下文: 我正在努力实现 @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
的作者似乎以不依赖于服务实现的方式实现了搜索效果。
使用简单的、基于 Http
的 searchBooks
实现,我不明白为什么需要 take(1)
或 takeUntil
- 因为可观察对象将完成并且switchMap
将确保不会发出 SearchCompleteAction
过时搜索的操作。