在鸿蒙应用开发中(特别是使用ArkUI框架时),你可以像在标准JavaScript/TypeScript中一样使用Promise来处理异步操作。以下是详细使用方法:

基本Promise使用

1. 创建Promise

function asyncOperation(): Promise<string> {
  return new Promise((resolve, reject) => {
    // 模拟异步操作
    setTimeout(() => {
      const success = Math.random() > 0.5;
      if (success) {
        resolve("操作成功");
      } else {
        reject(new Error("操作失败"));
      }
    }, 1000);
  });
}

2. 使用Promise

// 在ets文件中使用
async function fetchData() {
  try {
    const result = await asyncOperation();
    console.log("结果:", result);
  } catch (error) {
    console.error("错误:", error.message);
  }
}

// 或者使用then/catch
asyncOperation()
  .then(result => {
    console.log("结果:", result);
  })
  .catch(error => {
    console.error("错误:", error.message);
  });

鸿蒙中常见的Promise应用场景

1. 网络请求

import http from '@ohos.net.http';

function httpGet(url: string): Promise<string> {
  return new Promise((resolve, reject) => {
    let httpRequest = http.createHttp();
    httpRequest.request(
      url,
      {
        method: 'GET'
      },
      (err, data) => {
        if (err) {
          reject(err);
        } else {
          resolve(data.result as string);
        }
      }
    );
  });
}

// 使用
async function loadData() {
  try {
    const data = await httpGet('https://api.example.com/data');
    console.log('获取的数据:', data);
  } catch (error) {
    console.error('请求失败:', error);
  }
}

2. 文件操作

import fileio from '@ohos.fileio';

function readFile(filePath: string): Promise<string> {
  return new Promise((resolve, reject) => {
    fileio.readText(filePath, (err, data) => {
      if (err) {
        reject(err);
      } else {
        resolve(data);
      }
    });
  });
}

3. 设备能力调用

import geolocation from '@ohos.geolocation';

function getLocation(): Promise<geolocation.Location> {
  return new Promise((resolve, reject) => {
    geolocation.getCurrentLocation({
      priority: geolocation.LocationPriority.FIRST_FIX,
      timeInterval: 1,
      distanceInterval: 0
    }, (err, data) => {
      if (err) {
        reject(err);
      } else {
        resolve(data);
      }
    });
  });
}

在ArkUI组件中使用Promise

@Entry
@Component
struct MyComponent {
  @State message: string = '准备加载...';

  async aboutToAppear() {
    try {
      this.message = '加载中...';
      const result = await this.loadData();
      this.message = `加载完成: ${result}`;
    } catch (error) {
      this.message = `加载失败: ${error.message}`;
    }
  }

  loadData(): Promise<string> {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve('数据内容');
      }, 2000);
    });
  }

  build() {
    Column() {
      Text(this.message)
        .fontSize(20)
        .margin(10)
    }
    .width('100%')
    .height('100%')
  }
}

注意事项

  1. 鸿蒙的API有些是回调形式的,你可以用Promise包装它们

  2. UI更新必须在主线程进行,确保异步操作后的UI更新正确

  3. 使用async/await时,错误处理很重要,不要忘记try/catch

  4. 在组件销毁时,应取消未完成的异步操作以避免内存泄漏

高级技巧 - Promise工具函数

// 并行执行多个Promise
async function fetchAllData() {
  try {
    const [data1, data2] = await Promise.all([
      httpGet('https://api.example.com/data1'),
      httpGet('https://api.example.com/data2')
    ]);
    console.log('所有数据:', data1, data2);
  } catch (error) {
    console.error('获取数据失败:', error);
  }
}

// 超时控制
function withTimeout<T>(promise: Promise<T>, timeout: number): Promise<T> {
  return Promise.race([
    promise,
    new Promise<never>((_, reject) => {
      setTimeout(() => reject(new Error('操作超时')), timeout);
    })
  ]);
}

在鸿蒙开发中合理使用Promise可以使异步代码更清晰、更易于维护,特别是在处理复杂的异步流程时。

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐