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
相关产品推荐
相关产品推荐

