Observables:在新的订阅调用中取消之前的 http 请求
Observables : Cancel previous http request on new subscription call
我正在为我的项目开发搜索功能。一旦用户在搜索栏上输入任何内容;在搜索文本发生任何变化时,我会将文本发送到后端进行验证并收到响应(文本有无错误):
this.searchBar.on('change', () => {
http.post('api_link', {searchText:
this.serachBar.searchText}).subscribe(resp => {
this.resp = resp['Result'];
});
})
现在,当用户在搜索栏中连续输入时,多个验证响应会通过后端传入。但是,对于任何新的更改,只有最新的订阅有效,之前对 api 的任何调用都是无用的。
有什么方法可以在使用订阅对 api 的任何新呼叫中取消之前的订阅吗?
注意:似乎可以只等待所有响应,但我还将在搜索栏下方显示响应(在此之前显示加载器)。因此,与其在各种响应状态之间转换,我希望加载程序继续加载直到最新的响应可用。
您需要使用 debounceTime 和 switchMap 运算符。
this.searchBar.on('change', () => {
of(this.serachBar.searchText).pipe(
debounceTime(400),
distinctUntilChanged(),
switchMap((text)=> {
return http.post('api_link', {searchText: text}).map(resp => {
return resp['Result'];
});
});
).subscribe(response=> console.log(response));
});
我会使用一个主题来保持一切反应。在您的模板中 html 监听更改事件并向主题发出新值。
<searchBar (change)="search$.next($event.target.value)" />
然后在你的组件中:
this.subscription = this.search$.pipe(
debounceTime(800),
distinctUntilChanged(),
switchMap(searchText=>http.post('api_link', {searchText})
}).subscribe(response=>{
this.response = response.
});
如果通过主题发出新值,switchMap 将取消任何尚未完成的 HTTP 请求。你可以玩 debouneTime 看看什么适合你。最后,确保您在 ngOnDestroy 中取消订阅您的主题,这将阻止任何内存链接并保持一切良好和性能。:
ngOnDestroy(){
this.subscription.unsubscribe();
}
Suresh 的 有一个 distinctUntilChanged()
,这是对解决方案的极好补充。我正在添加它,但想在下面感谢他的回答。这是一个好处,因为如果我搜索 egg
就会发出请求。但是后来我添加了一个 s
egg 的结尾,并在去抖动完成之前改变了主意,另一个重复的 HTTP post 将不会搜索 egg。
我正在为我的项目开发搜索功能。一旦用户在搜索栏上输入任何内容;在搜索文本发生任何变化时,我会将文本发送到后端进行验证并收到响应(文本有无错误):
this.searchBar.on('change', () => {
http.post('api_link', {searchText:
this.serachBar.searchText}).subscribe(resp => {
this.resp = resp['Result'];
});
})
现在,当用户在搜索栏中连续输入时,多个验证响应会通过后端传入。但是,对于任何新的更改,只有最新的订阅有效,之前对 api 的任何调用都是无用的。
有什么方法可以在使用订阅对 api 的任何新呼叫中取消之前的订阅吗?
注意:似乎可以只等待所有响应,但我还将在搜索栏下方显示响应(在此之前显示加载器)。因此,与其在各种响应状态之间转换,我希望加载程序继续加载直到最新的响应可用。
您需要使用 debounceTime 和 switchMap 运算符。
this.searchBar.on('change', () => {
of(this.serachBar.searchText).pipe(
debounceTime(400),
distinctUntilChanged(),
switchMap((text)=> {
return http.post('api_link', {searchText: text}).map(resp => {
return resp['Result'];
});
});
).subscribe(response=> console.log(response));
});
我会使用一个主题来保持一切反应。在您的模板中 html 监听更改事件并向主题发出新值。
<searchBar (change)="search$.next($event.target.value)" />
然后在你的组件中:
this.subscription = this.search$.pipe(
debounceTime(800),
distinctUntilChanged(),
switchMap(searchText=>http.post('api_link', {searchText})
}).subscribe(response=>{
this.response = response.
});
如果通过主题发出新值,switchMap 将取消任何尚未完成的 HTTP 请求。你可以玩 debouneTime 看看什么适合你。最后,确保您在 ngOnDestroy 中取消订阅您的主题,这将阻止任何内存链接并保持一切良好和性能。:
ngOnDestroy(){
this.subscription.unsubscribe();
}
Suresh 的 distinctUntilChanged()
,这是对解决方案的极好补充。我正在添加它,但想在下面感谢他的回答。这是一个好处,因为如果我搜索 egg
就会发出请求。但是后来我添加了一个 s
egg 的结尾,并在去抖动完成之前改变了主意,另一个重复的 HTTP post 将不会搜索 egg。