【成长纪实】Flutter中Dart 与Harmony中 ArkTS 异步编程对比:从 Future 到 Promise
异步编程是现代应用开发的核心能力,特别是在处理I/O操作、网络请求和用户交互时。Dart 和 ArkTS 都提供了强大的异步编程支持,但在实现方式和语法细节上存在显著差异。本文将深入对比这两种语言的异步编程特性。
一、核心概念对比
1. 异步基础模型
Dart:
-
基于
Future
和Stream
的异步模型 -
单线程事件循环 + 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);// 创建超时 Promiseconst 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/catch 或 catchError | try/catch 或 catch | 基本相同 |
并行执行 | 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:
-
理解
Future
与Promise
的等价关系 -
学习 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