You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中点击事件终止旧请求并发起新请求的实现方案

解决方案:Angular中终止旧API请求并发起新请求

核心思路

用一个可重复触发的Subject作为取消信号,每次调用getData时先发送信号终止所有未完成的旧请求,再发起新请求。组件销毁时用另一个Subject清理所有请求,避免内存泄漏。

完整代码实现

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

@Component({
  selector: 'app-your-component',
  templateUrl: './your-component.component.html'
})
export class YourComponent implements OnInit, OnDestroy {
  // 组件销毁时清理所有请求
  private unSubscribe$ = new Subject<void>();
  // 每次点击时终止旧请求
  private cancelRequests$ = new Subject<void>();

  constructor(private service: YourDataService) {}

  ngOnInit(): void {
    this.getData('');
  }

  getData(data: string): void {
    // 发送信号终止所有未完成的旧请求
    this.cancelRequests$.next();

    // 发起新请求,绑定双重取消信号:点击触发 + 组件销毁触发
    const amount$ = this.service.getAmount(data).pipe(
      takeUntil(this.cancelRequests$),
      takeUntil(this.unSubscribe$)
    );
    const rate$ = this.service.getRate(data).pipe(
      takeUntil(this.cancelRequests$),
      takeUntil(this.unSubscribe$)
    );
    const applications$ = this.service.getApp(data).pipe(
      takeUntil(this.cancelRequests$),
      takeUntil(this.unSubscribe$)
    );
    const statistics$ = this.service.getStat(data).pipe(
      takeUntil(this.cancelRequests$),
      takeUntil(this.unSubscribe$)
    );

    // 处理应用数据请求
    applications$.subscribe({
      next: (res) => {
        if (res.success) {
          const d = res.dataSet;
          // 这里添加你的业务逻辑
        }
      },
      error: (err) => {
        // 处理错误
      }
    });

    // 处理金额数据请求
    amount$.subscribe({
      next: (res) => {
        // 金额数据处理逻辑
      },
      error: (err) => {
        // 处理错误
      }
    });

    // 处理汇率数据请求
    rate$.subscribe({
      next: (res) => {
        // 汇率数据处理逻辑
      },
      error: (err) => {
        // 处理错误
      }
    });

    // 处理统计数据请求
    statistics$.subscribe({
      next: (res) => {
        // 统计数据处理逻辑
      },
      error: (err) => {
        // 处理错误
      }
    });
  }

  ngOnDestroy(): void {
    // 组件销毁时彻底清理所有Subject
    this.unSubscribe$.next();
    this.unSubscribe$.complete();
    this.cancelRequests$.next();
    this.cancelRequests$.complete();
  }
}

HTML部分保持原有逻辑:

<button type="button" (click)="getData('abc')">Event</button>

关键细节说明

  • cancelRequests$ Subject:每次调用getData时先执行next(),所有绑定了takeUntil(this.cancelRequests$)的旧请求会立即终止。
  • 双重takeUntil:每个请求同时监听点击触发的取消信号和组件销毁的取消信号,确保所有场景下的请求都能被及时清理。
  • 内存泄漏防护:在ngOnDestroy中调用next()和complete(),彻底释放Subject资源,避免内存泄漏。

可选优化:用forkJoin统一处理所有请求

如果四个请求需要全部完成后再处理业务逻辑,可以用forkJoin合并请求,简化代码:

import { forkJoin } from 'rxjs';

// ...

getData(data: string): void {
  this.cancelRequests$.next();

  forkJoin([
    this.service.getAmount(data),
    this.service.getRate(data),
    this.service.getApp(data),
    this.service.getStat(data)
  ]).pipe(
    takeUntil(this.cancelRequests$),
    takeUntil(this.unSubscribe$)
  ).subscribe({
    next: ([amountRes, rateRes, appRes, statRes]) => {
      // 统一处理所有请求结果
      if (appRes.success) {
        const d = appRes.dataSet;
      }
    },
    error: (err) => {
      // 统一处理错误
    }
  });
}

内容的提问来源于stack exchange,提问作者Ricky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 21:00:58