异步函数同步执行致弹窗延迟:如何修改代码实现立即弹窗?
实现点击后立即打开弹窗并异步加载数据的方案
核心思路
原代码会等待两个异步请求全部完成后才打开弹窗,导致用户点击后有明显延迟。要实现弹窗立即显示,需先打开带加载状态的弹窗,再并行发起异步请求,请求完成后更新弹窗内的数据。
代码修改步骤
1. 修改openInfo函数
调整逻辑顺序,优先打开弹窗,再处理异步请求并更新弹窗数据:
async openInfo(e: any, x: any, y: any) { let dialogRef; try { // 立即打开弹窗,传入初始状态数据 dialogRef = this.dialog.open(InformationComponent, { data: { arch: null, closestArch: null, lang: this.browserLang, isLoading: true, hasError: false }, panelClass: 'custom-dialog-container' }); // 并行发起两个异步请求,不阻塞弹窗显示 const closestArchPromise = this.siteservice.GetClosetsSites(e.wgS84_Info.geography); const siteIdPromise = this.siteservice.GetSiteId(e.resourceID).toPromise(); const [closestArch, siteId] = await Promise.all([closestArchPromise, siteIdPromise]); // 请求完成后更新弹窗数据 dialogRef.componentInstance.data = { arch: siteId, closestArch: closestArch, lang: this.browserLang, isLoading: false, hasError: false }; // 若视图未自动更新,手动触发变更检测 dialogRef.componentInstance.cdr.detectChanges(); } catch (error) { console.log(error); // 请求失败时更新弹窗错误状态 if (dialogRef) { dialogRef.componentInstance.data = { ...dialogRef.componentInstance.data, isLoading: false, hasError: true }; dialogRef.componentInstance.cdr.detectChanges(); } } }
2. 调整InformationComponent组件
确保组件能接收并响应数据更新,处理视图变更:
import { Component, Inject, ChangeDetectorRef } from '@angular/core'; import { MAT_DIALOG_DATA } from '@angular/material/dialog'; @Component({ selector: 'app-information', templateUrl: './information.component.html' }) export class InformationComponent { constructor( @Inject(MAT_DIALOG_DATA) public data: any, public cdr: ChangeDetectorRef // 注入变更检测器,用于手动更新视图 ) {} }
3. 弹窗模板添加状态展示
在弹窗HTML模板中,根据状态展示对应内容:
<!-- 加载状态 --> <div *ngIf="data.isLoading" class="loading-container"> <span>加载中...</span> <!-- 可替换为自定义加载动画 --> </div> <!-- 数据展示状态 --> <div *ngIf="!data.isLoading && !data.hasError" class="content-container"> <p>站点ID: {{ data.arch }}</p> <p>最近站点: {{ data.closestArch }}</p> <!-- 其他业务内容 --> </div> <!-- 错误状态 --> <div *ngIf="!data.isLoading && data.hasError" class="error-container"> <span>数据加载失败,请稍后重试</span> </div>
关键说明
- 先开弹窗:让用户点击后立即获得反馈,消除感知延迟
- 并行请求:保留原
Promise.all的并行逻辑,不降低请求效率 - 状态管理:通过
isLoading和hasError明确告知用户数据加载状态
内容的提问来源于stack exchange,提问作者otacksverflow
相关产品推荐
相关产品推荐

