弹窗关闭延迟
======

#### 问题现象

提示弹窗在页面加载较慢时能够提供良好的用户体验。但若页面加载完成后弹窗仍未关闭，则会影响正常使用。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/5b/v3/fc66aZ7USkK-VQtcXglBYw/zh-cn_image_0000002628899074.png?HW-CC-KV=V1&HW-CC-Date=20260709T133813Z&HW-CC-Expire=86400&HW-CC-Sign=F6C76C2CAF6686EE8184378AFEC9075D1113C7757F192017024C30DC08D2502F "点击放大")

#### 背景知识

*   [CustomDialog](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-methods-custom-dialog-box)：通过CustomDialogController类显示自定义弹窗。使用弹窗组件时，优先考虑自定义弹窗，便于弹窗样式与内容的自定义。
*   [LoadingDialog](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ohos-arkui-advanced-dialog#loadingdialog)：进度加载类弹出框，操作正在执行时的提示信息。
*   [async/await](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/async-concurrency-overview#asyncawait)是一种用于处理异步操作的Promise语法糖，使得编写异步代码变得更加简单和易读。通过使用async关键字声明一个函数为异步函数，并使用await关键字等待Promise的解析（完成或拒绝），以同步的方式编写异步操作的代码。

#### 问题定位

1.  使用DevEco Testing查看问题组件，该问题组件为Dialog组件。![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/26/v3/wDvfRjw5RBu99EhuGHuqxA/zh-cn_image_0000002659258285.png?HW-CC-KV=V1&HW-CC-Date=20260709T133813Z&HW-CC-Expire=86400&HW-CC-Sign=F96D8DFE4E5C68E07E0B206C835EC106FA6C1869C5FE24443FA30549DAA94F14 "点击放大")
2.  排查弹窗Dialog的相关设置，应用使用async和await，在加载完成后台数据时才关闭加载弹窗，导致前台页面显示完成时加载弹窗仍在显示。
    
    @CustomDialog
    @Component
    struct LoadingDialogExample {
      controller?: CustomDialogController;
    
    
      build() {
        Row() {
          LoadingProgress()
            .width('40%')
            .height('100%')
            .margin({ left: 10 })
          Text('加载中')
            .fontSize(20)
            .width('40%')
            .height('100%')
            .textAlign(TextAlign.Start)
            .margin({ left: 2 })
        }
        .width('100%')
        .height('100%')
      }
    }
    
    
    @Entry
    @Component
    struct Index {
      @State content: string = '';
      dialogController: CustomDialogController = new CustomDialogController({
        builder: LoadingDialogExample(),
        width: 250,
        height: 60,
        cornerRadius: 10
      })
    
    
      async aboutToAppear(): Promise<void> {
        this.dialogController.open();
        await loadForeData().then((data) => {
          this.content = data;
        }); _// 加载前端数据_
        await myAsyncFunction(); _// 加载后端数据_
        this.dialogController.close();
      }
    
    
      build() {
        Column() {
          Text(this.content)
            .fontSize(20)
            .height('10%')
            .width('100%')
            .textAlign(TextAlign.Center)
        }
        .height('100%')
        .width('100%')
      }
    }
    
    
    async function myAsyncFunction(): Promise<void> {
      const result: string = await new Promise((resolve: Function) => {
       _ // 模拟加载数据_
        setTimeout(() => {
          resolve('Hello, world!');
        }, 3000);
      });
    }
    
    
    async function loadForeData(): Promise<string> {
      const result: string = await new Promise((resolve: Function) => {
       _ // 模拟加载数据_
        setTimeout(() => {
          resolve('Hello, world!');
        }, 1000);
      });
      return '测试页面';
    }
    

#### 分析结论

应用使用async和await，在加载完成后台数据时才关闭加载弹窗，导致前台页面显示完成时加载弹窗仍在显示。

#### 修改建议

加载完成前台数据后及时关闭加载弹窗，不使用await等待后台数据加载完成。

@CustomDialog
@Component
struct LoadingDialogExample {
  controller?: CustomDialogController;


  build() {
    Row() {
      LoadingProgress()
        .width('40%')
        .height('100%')
        .margin({ left: 10 });
      Text('加载中')
        .fontSize(20)
        .width('40%')
        .height('100%')
        .textAlign(TextAlign.Start)
        .margin({ left: 2 });
    }
    .width('100%')
    .height('100%');
  }
}


@Entry
@Component
struct Dialog {
  @State content: string = '';
  dialogController: CustomDialogController = new CustomDialogController({
    builder: LoadingDialogExample(),
    width: 250,
    height: 60,
    cornerRadius: 10
  });


  async aboutToAppear(): Promise<void> {
    this.dialogController.open();
    await loadForeData().then((data) => {
      this.content = data;
    });
    myAsyncFunction();
    this.dialogController.close();
  }


  build() {
    Column() {
      Text(this.content)
        .fontSize(20)
        .height('10%')
        .width('100%')
        .textAlign(TextAlign.Center);
    }
    .height('100%')
    .width('100%');
  }
}


async function myAsyncFunction(): Promise<void> {
  const result: string = await new Promise((resolve: Function) => {
 _   // 模拟加载数据_
    setTimeout(() => {
      resolve('Hello, world!');
    }, 3000);
  });
  console.info(result);
}


async function loadForeData(): Promise<string> {
  const result: string = await new Promise((resolve: Function) => {
   _ // 模拟加载数据_
    setTimeout(() => {
      resolve('Hello, world!');
    }, 1000);
  });
  console.info(result);
  return '测试页面';
}

效果图如下：

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/35/v3/HecdXxwNTMOe5OFky-WtPQ/zh-cn_image_0000002659138345.png?HW-CC-KV=V1&HW-CC-Date=20260709T133813Z&HW-CC-Expire=86400&HW-CC-Sign=1F2DBD433200928EE66F82EB7571C02E96BCE75DEA3AFD8EFE78690091195982 "点击放大")