Sib*_*raj 30 rxjs typescript angular-http-interceptors angular
如何取消/中止所有挂起的HTTP请求的角度4+.
有一种unsubscribe方法可以取消HTTP请求,但是如何一次取消所有待处理的请求.
特别是路线变化时.
我做了一件事
ngOnDestroy() {
this.subscription.unsubscribe();
}
Run Code Online (Sandbox Code Playgroud)
但如何在全球实现这一目标
有任何想法吗?
Ale*_*ues 49
takeUntil()从RxJS 签出运营商以全局删除您的订阅:
- RxJS 6+(使用pipe语法)
import { takeUntil } from 'rxjs/operators';
export class YourComponent {
protected ngUnsubscribe: Subject<void> = new Subject<void>();
[...]
public httpGet(): void {
this.http.get()
.pipe( takeUntil(this.ngUnsubscribe) )
.subscribe( (data) => { ... });
}
public ngOnDestroy(): void {
// This aborts all HTTP requests.
this.ngUnsubscribe.next();
// This completes the subject properlly.
this.ngUnsubscribe.complete();
}
}
Run Code Online (Sandbox Code Playgroud)
- RxJS <6
import 'rxjs/add/operator/takeUntil'
export class YourComponent {
protected ngUnsubscribe: Subject<void> = new Subject<void>();
[...]
public httpGet(): void {
this.http.get()
.takeUntil(this.ngUnsubscribe)
.subscribe( (data) => { ... })
}
public ngOnDestroy(): void {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}
}
Run Code Online (Sandbox Code Playgroud)
你基本上可以发出你的退订事件Subject使用next()每次要完成一堆流.在组件被销毁时,取消订阅活动Observable也是一种好习惯,以避免内存泄漏.
值得阅读 :
Bla*_*ito 29
您可以创建一个拦截器以将takeUntil操作符应用于每个请求.然后在路线更改时,您将发出取消所有待处理请求的值.
@Injectable()
export class HttpCancelInterceptor implements HttpInterceptor {
constructor(private httpCancelService: HttpCancelService) { }
intercept<T>(req: HttpRequest<T>, next: HttpHandler): Observable<HttpEvent<T>> {
return next.handle(req).pipe(takeUntil(this.httpCancelService.onCancelPendingRequests()))
}
}
Run Code Online (Sandbox Code Playgroud)
帮手服务.
@Injectable()
export class HttpCancelService {
private cancelPendingRequests$ = new Subject<void>()
constructor() { }
/** Cancels all pending Http requests. */
public cancelPendingRequests() {
this.cancelPendingRequests$.next()
}
public onCancelPendingRequests() {
return this.cancelPendingRequests$.asObservable()
}
}
Run Code Online (Sandbox Code Playgroud)
路线上的钩子会在应用程序中发生变化(例如应用程序组件).
this.router.events.subscribe(event => {
if (event instanceof ActivationEnd) {
this.httpCancelService.cancelPendingRequests()
}
})
Run Code Online (Sandbox Code Playgroud)
Ant*_*Lee 10
如果您不想手动取消订阅所有订阅,则可以执行以下操作:
export function AutoUnsubscribe(constructor) {
const original = constructor.prototype.ngOnDestroy;
constructor.prototype.ngOnDestroy = function() {
for (const prop in this) {
if (prop) {
const property = this[prop];
if (property && (typeof property.unsubscribe === 'function')) {
property.unsubscribe();
}
}
}
if (original && typeof original === 'function') {
original.apply(this, arguments)
};
};
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以将其用作组件中的装饰器
@AutoUnsubscribe
export class YourComponent {
}
Run Code Online (Sandbox Code Playgroud)
但您仍需要将订阅存储为组件属性.当您导出组件时,将发生AutoUnsubscribe功能.
我不相信需要所请求的功能,但您可以实现这一点,通过包装框架的 http 服务并委托给它,随时随地取消所有未完成的请求。
然而,当我们开始实施这项服务时,一个问题很快就会显现出来。一方面,我们希望避免更改现有代码,包括利用现有 Angular http 客户端的第三方代码。另一方面,我们希望避免实现继承。
为了两全其美,我们可以使用包装器实现AngularHttp服务。现有代码将继续工作而无需更改(前提是所述代码不会像 use 那样做任何愚蠢的事情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[] = [];
}
Run Code Online (Sandbox Code Playgroud)
请注意,合并了interface和class声明CancellationAwareHttpClient。通过这种方式,我们班器具 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 {}
Run Code Online (Sandbox Code Playgroud)
请注意我们如何覆盖现有框架提供的服务。我们使用工厂来创建我们的实例,并且不会为 DI 添加任何装饰器到包装器本身,以避免注入器中的循环。
ngOnDestroy回调通常用于实例被销毁时需要进行的任何自定义清理。
您想在哪里取消您的请求?
也许如果你想取消浏览器关闭时的请求,这里有一个创意
| 归档时间: |
|
| 查看次数: |
27579 次 |
| 最近记录: |