首页 > 解决方案 > Angular 在取消订阅时不会取消包装的 HTTP 请求

问题描述

更新:为什么你不能只使用或返回内置的HttpClient?因为我们必须拦截响应。

我们有一个HttpService包装了HttpClientangular 提供的内容。它用于应用标头/授权并对响应执行一些操作(......就像拦截器 - 我们走这条路是因为当时拦截器不在 Angular 中)。

我们的 HttpService 非常接近HttpClient并且有类似的方法,比如GET,POST等等。我们将GET在这里作为一个例子。

我意识到,在取消订阅这些方法时,real HttpClient 取消了请求,而wrapped HttpService 没有取消了请求在 Stackblitz 上查看此演示

所以,我的问题是:如何强制取消取消订阅的请求?或者,我的实施是否 Observable.create错误(见下文)?

下面是一个关于 GET 的例子(实际代码做的更多):

@Injectable()
export class HttpService {

    constructor(private http: HttpClient) {}

    public get<T>(url: string): Observable<any> {
        return Observable.create(observer => {
            this.http.get<T>(url).subscribe(
                response =>  {
                     // some other things
                     observer.next(response);
                 },
                error =>  observer.error(error),
                () =>  observer.complete());
        });
    }
}

以下是网络截图: 在此处输入图像描述

标签: angularhttpangular-http

解决方案


传递给 create 函数的函数应该包含拆解逻辑。注意它是如何在其文档中声明的:

create(onSubscription: function(observer: Observer): TeardownLogic): Observable

相关的部分是TeardownLogic

不带参数的函数。当创建的 Observable 的消费者调用 unsubscribe 时,该函数将被调用

所以你的代码应该看起来更像这样:

public get<T>(url: string): Observable<any> {
    return Observable.create(observer => {
        let subs = this.http.get<T>(url).subscribe(
            response =>  {
                 // some other things
                 observer.next(response);
             },
            error =>  observer.error(error),
            () =>  observer.complete());

        return () => {
            // Your own tear down logic here and then:
            subs.unsubscribe();
        };
    });
}

推荐阅读