使用可观察量的 HTTP 服务请求落后一个值

问题描述 投票:0回答:1

我有下面的 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);
    }
}
angular http rxjs
1个回答
0
投票

您遇到的问题是由于

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 请求中的错误处理,例如捕获错误和处理加载状态,以提高服务的稳健性和用户体验。

© www.soinside.com 2019 - 2024. All rights reserved.