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

Angular应用打印、下载PDF时加载Spinner未等待异步请求完成的解决求助

问题根因

你代码中 forEach 循环内发起的是异步HTTP请求,JavaScript主线程不会等待这些异步请求执行完成,会直接执行循环后的关闭Spinner逻辑,因此出现Spinner提前关闭的问题。

修复方案

使用RxJS的forkJoin操作符,它会等待所有传入的Observable都完成后再触发回调,你可以在回调中统一处理返回结果、关闭Spinner。

修复后代码

import { forkJoin } from 'rxjs'; // 代码顶部引入forkJoin

print() {
  // 启动Spinner
  this.sharedService.loadingSpinner = true;
  // 收集所有打印请求的Observable
  const printRequests = selectedDocuments.map(x => this.calculator.printPolicy(policyId, x));

  // 等待所有请求完成
  forkJoin(printRequests).subscribe({
    next: (responses) => {
      // 遍历处理每个请求的返回结果
      responses.forEach(res => {
        const base64str = res["bBlob_PDF"];
        const binary = atob(base64str.replace(/\s/g, ""));
        const len = binary.length;
        const buffer = new ArrayBuffer(len);
        let view = new Uint8Array(buffer);
        for (let i = 0; i < len; i++) {
          view[i] = binary.charCodeAt(i);
        }
        const URLObject = URL.createObjectURL(new Blob([view], { type: "application/pdf" }));
        window.open(URLObject, "_blank");
        const a = document.createElement("a");
        a.href = URLObject;
        a.download = "MyHome_" + policyId + ".pdf";
        // a.click();
      })
    },
    error: (err) => {
      // 可选:请求异常时的处理逻辑,避免Spinner一直加载
      console.error('打印请求失败', err);
    },
    complete: () => {
      // 所有请求处理完成后关闭Spinner
      this.sharedService.loadingSpinner = false;
      this.hasBeenPrinted = true;
    }
  })
}

注意事项

  • 如果需要支持部分请求失败时仍处理成功的请求,可以将每个printPolicy请求通过catchError操作符处理异常,避免单个请求失败导致forkJoin整体触发错误回调
  • 每次调用URL.createObjectURL生成的对象URL用完后建议调用URL.revokeObjectURL释放内存,避免内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 04:36:04