page fortawesome fontawesome font cli bootstrap awesome angular typescript rxjs angular-http-interceptors

fortawesome - install font awesome angular 6



Cómo cancelar/cancelar la suscripción de todas las solicitudes HTTP pendientes angular 4+ (7)

No estoy convencido de la necesidad de la funcionalidad solicitada, pero puede lograrlo, cancelando todas las solicitudes pendientes cuando y donde desee, envolviendo el servicio http del marco y delegando en él.

Sin embargo, cuando implementamos este servicio, un problema se hace evidente rápidamente. Por un lado, nos gustaría evitar cambiar el código existente, incluido el código de terceros, que aprovecha el cliente http angular de Stock. Por otro lado, nos gustaría evitar la herencia de implementación.

Para obtener lo mejor de ambos mundos, podemos implementar el servicio Angular Http con nuestro contenedor. El código existente continuará funcionando sin cambios (siempre que dicho código no haga nada estúpido como usar 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[] = []; }

Tenga en cuenta que la interface y class declaraciones de class para CancellationAwareHttpClient de CancellationAwareHttpClient se fusionan. De esta manera, nuestra clase implementa Http en virtud de la cláusula de extends la declaración de interface .

Ahora brindaremos nuestro servicio.

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 {}

Observe cómo anulamos el servicio proporcionado por el marco existente. Usamos una fábrica para crear nuestra instancia y no agregamos decoradores para DI al envoltorio para evitar un ciclo en el inyector.

Cómo cancelar / abortar todas las solicitudes HTTP pendientes angular 4+.

Existe un método para cancelar la unsubscribe para cancelar solicitudes HTTP, pero cómo cancelar todas las solicitudes pendientes de una vez.

Especialmente en el cambio de ruta.

Hay una cosa que hice

ngOnDestroy() { this.subscription.unsubscribe(); }

Pero, ¿cómo lograr esto globalmente?

¿Algunas ideas?


Prueba esto :

import { Component, OnInit, OnDestroy } from ''@angular/core''; import { Subscription } from ''rxjs/Rx''; export class Component implements OnInit, OnDestroy { private subscription: Subscription; ngOnInit() { this.subscription = this.route.params.subscribe(); } ngOnDestroy() { this.subscription.unsubscribe(); } }


Puede crear un Servicio HTTP personalizado (utilizando HttpClient) que mantiene una lista de solicitudes pendientes. Siempre que nos envíe un servicio personalizado http en lugar de Http / HttpClient, ahora inserte las suscripciones en una lista y, al regresar de la respuesta, saque esa suscripción. Usando esto tendrás todas las suscripciones incompletas en una lista.

Ahora en el mismo servicio personalizado Inyectar enrutador en el constructor y suscribirse en él para obtener los eventos de cambio de ruta. Ahora, cada vez que este observable emita, todo lo que necesita hacer es cancelar la suscripción de todas las suscripciones presentes en la lista y extraer todos los elementos de la misma.

Si necesita un fragmento de código, mencione en el comentario.


Puede crear un interceptor para aplicar el operador takeUntil a cada solicitud. Luego, en el cambio de ruta, emitirá un valor que cancelará todas las solicitudes pendientes.

@Injectable() export class HttpCancelInterceptor implements HttpInterceptor { constructor(private httpCancelService: HttpCancelService) { } intercept<T>(req: HttpRequest<T>, next: HttpHandler): Observable<HttpEvent<T>> { return next.handle(req).takeUntil(this.httpCancelService.onCancelPendingRequests()) } }

Servicio de ayuda.

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

Enganche los cambios de ruta en algún lugar de su aplicación (por ejemplo, el componente de la aplicación).

this.router.events.subscribe(event => { if (event instanceof ActivationEnd) { this.httpCancelService.cancelPendingRequests() } })


Si no desea cancelar la suscripción manual de todas las suscripciones, puede hacer esto:

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

Luego puedes usarlo como decorador en tu componente.

@AutoUnsubscribe export class YourComponent { }

pero aún necesita almacenar suscripciones como propiedades de componentes. Y cuando navegue fuera del componente, se producirá la función AutoUnsubscribe.


takeUntil() operador takeUntil() de RxJS para eliminar globalmente sus suscripciones:

- RxJS 6+ (usando la sintaxis de la 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(); } }

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

Básicamente, puede emitir un evento en su Subject cancelación de suscripción usando next() cada vez que desee completar un montón de secuencias. También es una buena práctica cancelar la suscripción a los Observables activos ya que el componente se destruye para evitar pérdidas de memoria.

Vale la pena leer :


ngOnDestroy devolución de llamada ngOnDestroy se usa normalmente para cualquier limpieza personalizada que deba ocurrir cuando se destruye la instancia.

¿Dónde quieres cancelar tu solicitud?

Tal vez si desea cancelar sus solicitudes en el navegador cerca hay una idea creativa here