我不相信需要所请求的功能,但您可以做到这一点,通过包装框架的 http 服务并委托给它,随时随地取消所有未完成的请求。
但是,当我们着手实施这项服务时,问题很快就会显现出来。一方面,我们希望避免更改现有代码,包括第三方代码,这些代码利用了现有的 Angular http 客户端。另一方面,我们希望避免实现继承。
为了两全其美,我们可以使用我们的包装器实现 Angular Http 服务。现有代码将继续工作而无需更改(前提是所述代码不会做任何愚蠢的事情,例如使用 http instanceof Http)。
import {Http, Request, RequestOptions, RequestOptionsArgs, Response} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import {Subscription} from 'rxjs/Subscription';
export default interface CancellationAwareHttpClient extends Http { }
export default class CancellationAwareHttpClient {
constructor(private wrapped: Http) {
const delegatedMethods: Array<keyof Http> = [
'get', 'post', 'put', 'delete',
'patch', 'head', 'options'
];
for (const key of delegatedMethods) {
this[key] = wrapped[key].bind(wrapped);
}
}
cancelOutstandingRequests() {
this.subscriptions.forEach(subscription => {
subscription.unsubscribe();
});
this.subscriptions = [];
}
request(url: string | Request, options?: RequestOptionsArgs) {
const subscription = this.wrapped.request(url, options);
this.subscriptions.push(subscription);
return subscription;
}
subscriptions: Subscription[] = [];
}
请注意,CancellationAwareHttpClient 的 interface 和 class 声明已合并。这样,我们的类实现 Http 凭借interface 声明的extends 子句。
现在我们将提供我们的服务
import {NgModule} from '@angular/core';
import {ConnectionBackend, RequestOptions} from '@angular/http';
import CancellationAwareHttpClient from 'app/services/cancellation-aware-http-client';
let cancellationAwareClient: CancellationAwareHttpClient;
const httpProvider = {
provide: Http,
deps: [ConnectionBackend, RequestOptions],
useFactory: function (backend: ConnectionBackend, defaultOptions: RequestOptions) {
if (!cancellationAwareClient) {
const wrapped = new Http(backend, defaultOptions);
cancellationAwareClient = new CancellationAwareHttpClient(wrappedHttp);
}
return cancellationAwareClient;
}
};
@NgModule({
providers: [
// provide our service as `Http`, replacing the stock provider
httpProvider,
// provide the same instance of our service as `CancellationAwareHttpClient`
// for those wanting access to `cancelOutstandingRequests`
{...httpProvider, provide: CancellationAwareHttpClient}
]
}) export class SomeModule {}
请注意我们如何覆盖现有框架提供的服务。我们使用工厂来创建我们的实例,并且不向包装器本身添加任何 DI 装饰器,以避免注入器中的循环。