Angular 取消订阅时不会取消包装的 HTTP 请求

Angular doesn't cancel a wrapped HTTP Request on Unsubscribing

Update: Why can't you just use or return the built in HttpClient? Because we have to intercept the response.

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

Our HttpService is very close to HttpClient and has similar methods like GET, POST, etc. We will use GET as an example here.

我意识到在取消订阅这些方法时,real HttpClient 取消请求,而 wrapped HttpService 不取消 请求See this demo on 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());
        });
    }
}

以下为网络截图:

httpclient returns 默认是一个可观察的,所以你不需要创建一个。它也会自动取消它。它应该是这样的:

public get<T>(url: string): Observable<T> {
    return this.http.get<T>(url).pipe(map(response => {
        // manipulate response here.

        return response;
    }));
}}

传递给创建函数的函数应该包括拆解逻辑。注意它是如何在 its docs:

中声明的
create(onSubscription: function(observer: Observer): TeardownLogic): Observable

相关的部分是 TeardownLogic:

Function that takes no parameters. When consumer of created Observable calls unsubscribe, that function will be called

因此您的代码应该更像这样:

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();
        };
    });
}