我有下面的 Angular 服务使用去抖时间发出 http 请求。我正在努力使其发挥作用,因为它是背后的一种价值,你能告诉我我做错了什么吗?还有我该如何改进?
class Service {
private searchSubject = new Subject<string>();
private value;
constructor(private http: HttpClient) {
this.searchSubject
.pipe(
debounceTime(500),
distinctUntilChanged(),
switchMap((searchTerm) => {
return this.http
.get('/search/locations')
.pipe(
map(response => response.content),
);
}),
)
.subscribe((value) => {
console.log(value); // Correct value on first value change
this.value = value;
});
}
getLocations(searchTerm: string): Observable<LocationInformationSearchHit[]> {
this.searchSubject.next(searchTerm);
console.log(this.value); // Value is 'undefined' and with one value behind on each new searchTerm change
return of(this.value);
}
}
您遇到的问题是由于
switchMap
运算符内 HTTP 请求的异步性质造成的。当您调用 this.searchSubject.next(searchTerm)
时,它会触发 HTTP 请求,但 this.value
会在 HTTP 请求完成之前立即返回。结果,this.value
是 undefined
或落后一个值。
要解决此问题,您需要从
switchMap
运算符返回可观察值,并在 getLocations
方法中订阅它。以下是修改代码的方法:
import { BehaviorSubject, Observable } from 'rxjs';
import { debounceTime, distinctUntilChanged, switchMap, map } from 'rxjs/operators';
class Service {
private searchSubject = new BehaviorSubject<string>('');
private value: LocationInformationSearchHit[];
constructor(private http: HttpClient) {
this.searchSubject
.pipe(
debounceTime(500),
distinctUntilChanged(),
switchMap((searchTerm) => {
return this.http
.get('/search/locations')
.pipe(
map(response => response.content),
);
}),
)
.subscribe((value) => {
console.log(value); // Correct value on first value change
this.value = value;
});
}
getLocations(searchTerm: string): Observable<LocationInformationSearchHit[]> {
this.searchSubject.next(searchTerm);
return this.searchSubject.asObservable(); // Return the observable from BehaviorSubject
}
}
通过这些更改,
getLocations
方法现在从searchSubject
返回可观察值,它将发出从 HTTP 请求接收到的最新值。无论您在哪里使用 getLocations
方法,都可以订阅此 observable 来获取最新的搜索结果。
此外,请考虑 HTTP 请求中的错误处理,例如捕获错误和处理加载状态,以提高服务的稳健性和用户体验。