返回

Angular路由跳转时如何取消所有未完成的HTTP请求?

前端

实现方案 监视路由切换事件; 编写路由守卫取消请求。

我们应该知道,当我们单击应用程序中的链接或在地址栏中输入URL时,Angular都会触发路由事件。我们可以使用路由事件来确定何时发生路由切换。我们可以在路由器模块中编写一个路由守卫,并在路由切换时取消所有未完成的HTTP请求。

要编写路由守卫,请在终端中运行以下命令:

ng g g services/cancel-http --skip-tests

这将在src / app / services目录中创建一个名为cancel-http.service.ts的新文件。在该文件中,我们将编写我们的路由守卫。路由守卫是一个类,它实现了CanDeactivate接口。CanDeactivate接口定义了一个名为canDeactivate的方法,该方法将在路由切换时被调用。在canDeactivate方法中,我们将取消所有未完成的HTTP请求。

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanDeactivate, RouterStateSnapshot } from '@angular/router';
import { Observable, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root',
})
export class CancelHttpService implements CanDeactivate<unknown> {
  private unsubscribe$ = new Subject<void>();

  constructor(private http: HttpClient) {}

  canDeactivate(
    component: unknown,
    currentRoute: ActivatedRouteSnapshot,
    currentState: RouterStateSnapshot,
    nextState: RouterStateSnapshot
  ): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    this.http.ongoingRequests.forEach((req) => {
      req.unsubscribe();
    });
    this.unsubscribe$.next();
    this.unsubscribe$.complete();
    return true;
  }
}

现在,我们需要将我们的路由守卫添加到路由器模块中。为此,请在终端中运行以下命令:

ng g module app-routing --flat --module=app

这将在src / app目录中创建一个名为app-routing.module.ts的新文件。在该文件中,我们将添加我们的路由守卫。

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CancelHttpService } from './services/cancel-http.service';

const routes: Routes = [
  {
    path: '',
    component: HomeComponent,
    canDeactivate: [CancelHttpService],
  },
  {
    path: 'about',
    component: AboutComponent,
    canDeactivate: [CancelHttpService],
  },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers: [CancelHttpService],
})
export class AppRoutingModule {}

现在,当我们单击应用程序中的链接或在地址栏中输入URL时,我们的路由守卫将被调用,并且所有未完成的HTTP请求都将被取消。