【成长纪实】Flutter中Dart 与Harmony中 ArkTS 异步编程对比:从 Future 到 Promise

异步编程是现代应用开发的核心能力,特别是在处理I/O操作、网络请求和用户交互时。Dart 和 ArkTS 都提供了强大的异步编程支持,但在实现方式和语法细节上存在显著差异。本文将深入对比这两种语言的异步编程特性。

一、核心概念对比

1. 异步基础模型

Dart:

  • 基于 FutureStream 的异步模型

  • 单线程事件循环 + Isolate(多线程)

  • 内置 async/await 语法糖

ArkTS:

  • 基于 Promise 的异步模型(继承自 JavaScript/TypeScript)

  • 单线程事件循环 + Worker(多线程)

  • 内置 async/await 语法糖

二、基本异步操作

1. 异步函数定义

Dart:

dart

复制代码
// 返回 Future 的异步函数
Future<String> fetchUserData(int userId) async {
  // 模拟异步操作
  await Future.delayed(Duration(seconds: 1));
  return '用户 $userId 的数据';
}

// 调用异步函数
void main() async {
  var data = await fetchUserData(123);
  print(data);
}

ArkTS:

typescript

复制代码
// 返回 Promise 的异步函数
async fetchUserData(userId: number): Promise<string> {
  // 模拟异步操作
  await new Promise(resolve => setTimeout(resolve, 1000));
  return `用户 ${userId} 的数据`;
}

// 调用异步函数
async function main(): Promise<void> {
  const data = await fetchUserData(123);
  console.log(data);
}

2. 错误处理

Dart:

dart

复制代码
Future<void> fetchWithErrorHandling() async {
  try {
    var data = await fetchUserData(123);
    print('成功: $data');
  } catch (e) {
    print('错误: $e');
  } finally {
    print('操作完成');
  }
}

// 或者使用 then/catchError
fetchUserData(123)
  .then((data) => print('成功: $data'))
  .catchError((e) => print('错误: $e'));

ArkTS:

typescript

复制代码
async fetchWithErrorHandling(): Promise<void> {
  try {
    const data = await fetchUserData(123);
    console.log(`成功: ${data}`);
  } catch (e) {
    console.log(`错误: ${e}`);
  } finally {
    console.log('操作完成');
  }
}

// 或者使用 then/catch
fetchUserData(123)
  .then((data: string) => console.log(`成功: ${data}`))
  .catch((e: any) => console.log(`错误: ${e}`));

三、并发异步操作

1. 并行执行多个异步任务

Dart:

dart

复制代码
Future<void> parallelTasks() async {
  // 同时启动多个异步任务
  var task1 = fetchUserData(1);
  var task2 = fetchUserData(2);
  var task3 = fetchUserData(3);
  
  // 等待所有任务完成
  var results = await Future.wait([task1, task2, task3]);
  print('所有结果: $results');
}

// 按顺序执行
Future<void> sequentialTasks() async {
  var result1 = await fetchUserData(1);
  var result2 = await fetchUserData(2);
  var result3 = await fetchUserData(3);
  print('顺序结果: $result1, $result2, $result3');
}

ArkTS:

typescript

复制代码
async parallelTasks(): Promise<void> {
  // 同时启动多个异步任务
  const task1 = fetchUserData(1);
  const task2 = fetchUserData(2);
  const task3 = fetchUserData(3);
  
  // 等待所有任务完成
  const results = await Promise.all([task1, task2, task3]);
  console.log(`所有结果: ${results}`);
}

// 按顺序执行
async sequentialTasks(): Promise<void> {
  const result1 = await fetchUserData(1);
  const result2 = await fetchUserData(2);
  const result3 = await fetchUserData(3);
  console.log(`顺序结果: ${result1}, ${result2}, ${result3}`);
}

2. 竞争操作(第一个完成的任务)

Dart:

dart

复制代码
Future<void> raceOperations() async {
  var fastTask = Future.delayed(Duration(milliseconds: 500), () => '快速任务');
  var slowTask = Future.delayed(Duration(seconds: 2), () => '慢速任务');
  
  var winner = await Future.any([fastTask, slowTask]);
  print('第一个完成: $winner'); // 输出: 第一个完成: 快速任务
}

ArkTS:

typescript

复制代码
async raceOperations(): Promise<void> {
  const fastTask = new Promise<string>(resolve => 
    setTimeout(() => resolve('快速任务'), 500));
  const slowTask = new Promise<string>(resolve => 
    setTimeout(() => resolve('慢速任务'), 2000));
  
  const winner = await Promise.race([fastTask, slowTask]);
  console.log(`第一个完成: ${winner}`); // 输出: 第一个完成: 快速任务
}

四、高级异步模式

1. 异步生成器(流处理)

Dart (使用 Stream):

dart

复制代码
// 创建异步流
Stream<int> countStream(int max) async* {
  for (int i = 1; i <= max; i++) {
    await Future.delayed(Duration(milliseconds: 500));
    yield i; // 产生值
  }
}

// 消费流
void consumeStream() async {
  await for (var value in countStream(5)) {
    print('收到值: $value');
  }
  print('流结束');
}

// 或者使用 listen
void listenStream() {
  countStream(3).listen(
    (value) => print('监听值: $value'),
    onDone: () => print('流完成'),
    onError: (e) => print('错误: $e')
  );
}

ArkTS (使用 AsyncGenerator):

typescript

复制代码
// 创建异步生成器
async function* countStream(max: number): AsyncGenerator<number, void, unknown> {
  for (let i = 1; i <= max; i++) {
    await new Promise(resolve => setTimeout(resolve, 500));
    yield i; // 产生值
  }
}

// 消费异步生成器
async function consumeStream(): Promise<void> {
  for await (const value of countStream(5)) {
    console.log(`收到值: ${value}`);
  }
  console.log('流结束');
}

2. 超时控制

Dart:

dart

复制代码
Future<void> fetchWithTimeout() async {
  var fetchTask = fetchUserData(123);
  
  try {
    // 设置超时
    var result = await fetchTask.timeout(Duration(seconds: 2));
    print('成功: $result');
  } on TimeoutException {
    print('请求超时');
  }
}

ArkTS:

typescript

复制代码
async function fetchWithTimeout(): Promise<void> {
  const fetchTask = fetchUserData(123);
  
  // 创建超时 Promise
  const timeout = new Promise<never>((_, reject) => 
    setTimeout(() => reject(new Error('请求超时')), 2000)
  );
  
  try {
    const result = await Promise.race([fetchTask, timeout]);
    console.log(`成功: ${result}`);
  } catch (e) {
    console.log(`错误: ${e}`);
  }
}

五、并发与隔离

1. 多线程处理

Dart (使用 Isolate):

dart

复制代码
// 在独立 Isolate 中执行耗时计算
Future<int> heavyComputation(int n) async {
  var receivePort = ReceivePort();
  
  await Isolate.spawn(_computeInIsolate, receivePort.sendPort);
  
  // 获取 isolate 的发送端口
  var sendPort = await receivePort.first as SendPort;
  
  var response = ReceivePort();
  sendPort.send([n, response.sendPort]);
  
  return await response.first as int;
}

// Isolate 中的计算函数
void _computeInIsolate(SendPort mainSendPort) {
  var receivePort = ReceivePort();
  mainSendPort.send(receivePort.sendPort);
  
  receivePort.listen((message) {
    var [data, replyTo] = message as List;
    var result = _fibonacci(data as int); // 耗时计算
    replyTo.send(result);
  });
}

int _fibonacci(int n) {
  if (n <= 1) return n;
  return _fibonacci(n - 1) + _fibonacci(n - 2);
}

ArkTS (使用 Worker):

typescript

复制代码
// main.ts
const worker = new Worker('worker.ts', { name: 'compute-worker' });

async function heavyComputation(n: number): Promise<number> {
  return new Promise((resolve, reject) => {
    worker.postMessage(n);
    
    worker.onmessage = (event: MessageEvent<number>) => {
      resolve(event.data);
    };
    
    worker.onerror = (error: ErrorEvent) => {
      reject(error.error);
    };
  });
}

// worker.ts
self.onmessage = (event: MessageEvent<number>) => {
  const n = event.data;
  const result = fibonacci(n); // 耗时计算
  self.postMessage(result);
};

function fibonacci(n: number): number {
  if (n <= 1) return n;
  return fibonacci(n - 1) + fibonacci(n - 2);
}

六、实际应用场景对比

1. 网络请求封装

Dart:

dart

复制代码
class ApiService {
  final HttpClient _client = HttpClient();
  
  Future<Map<String, dynamic>> get(String url) async {
    try {
      var request = await _client.getUrl(Uri.parse(url));
      var response = await request.close();
      
      if (response.statusCode == 200) {
        var jsonString = await response.transform(utf8.decoder).join();
        return jsonDecode(jsonString);
      } else {
        throw Exception('请求失败: ${response.statusCode}');
      }
    } catch (e) {
      throw Exception('网络错误: $e');
    }
  }
  
  Future<List<Map<String, dynamic>>> getMultiple(List<String> urls) async {
    var requests = urls.map((url) => get(url));
    return await Future.wait(requests);
  }
}

ArkTS:

typescript

复制代码
class ApiService {
  async get(url: string): Promise<any> {
    try {
      const response = await fetch(url);
      
      if (response.ok) {
        return await response.json();
      } else {
        throw new Error(`请求失败: ${response.status}`);
      }
    } catch (e) {
      throw new Error(`网络错误: ${e}`);
    }
  }
  
  async getMultiple(urls: string[]): Promise<any[]> {
    const requests = urls.map(url => this.get(url));
    return await Promise.all(requests);
  }
}

七、总结与核心差异表

特性 Dart ArkTS 关键差异
基本类型 Future<T> Promise<T> 概念相同,名称不同
异步函数 async/await async/await 语法几乎相同
错误处理 try/catchcatchError try/catchcatch 基本相同
并行执行 Future.wait() Promise.all() API 名称不同
竞争执行 Future.any() Promise.race() API 名称不同
流处理 Stream<T> + async*/yield AsyncGenerator Dart 的 Stream 更成熟,API 更丰富
超时控制 future.timeout() 手动实现或第三方库 Dart 内置支持更好
多线程 Isolate Worker 概念相似,Isolate 内存隔离更彻底
取消操作 StreamSubscription.cancel() AbortController Dart 的取消机制更统一

学习建议

从 Dart 到 ArkTS:

  • Future 思维转换为 Promise 思维

  • 熟悉 Promise.all()Promise.race() 等组合器

  • 了解 AsyncGenerator 作为 Stream 的替代方案

  • 掌握 Worker 作为 Isolate 的对应概念

从 ArkTS 到 Dart:

  • 理解 FuturePromise 的等价关系

  • 学习 Dart 更丰富的 Stream API

  • 掌握 Isolate 的强隔离特性

  • 利用 Dart 内置的超时和取消支持

两种语言在异步编程上都提供了优秀的支持,核心思想高度一致。主要的差异在于 API 命名和某些高级特性的实现方式。掌握这些差异后,你可以在 Flutter 和 HarmonyOS 开发中自如地进行异步编程

https://developer.huawei.com/consumer/cn/training/classDetail/fd34ff9286174e848d34cde7f512ce22?type=1%3Fha_source%3Dhmosclass&ha_sourceId=89000248

相关推荐
Swift社区6 小时前
在 HarmonyOS 中平滑切换“点状粒子”与“图片粒子”(含可运行 ArkTS 示例)
华为·harmonyos
猫林老师6 小时前
HarmonyOS多媒体开发:自定义相机与音频播放器实战
数码相机·音视频·harmonyos
逻极6 小时前
HarmonyOS 5 鸿蒙应用签名机制与安全开发实战指南
harmonyos
QuantumLeap丶8 小时前
《Flutter全栈开发实战指南:从零到高级》- 05 - 基础组件实战:构建登录界面
flutter·ios
黄毛火烧雪下8 小时前
(四)Flutter插件之IOS插件开发
flutter·ios
西西学代码9 小时前
Flutter---弹窗
flutter
RaidenLiu9 小时前
告别陷阱:精通Flutter Signals的生命周期、高级API与调试之道
前端·flutter·前端框架
—Qeyser11 小时前
Flutter字体引用与使用指南
flutter
zhuweisky12 小时前
实现一个纯血鸿蒙版(HarmonyOS)的聊天Demo,并可与其它PC、手机端互通!
harmonyos·im·聊天软件