大家好,我是 V 哥,很好奇,在ArkTS中实现异步编程是怎样的,今天的内容来聊聊这个问题,总结了一些学习笔记,分享给大家,在 ArkTS中实现异步编程主要可以通过以下几种方式:
1. 使用async
和await
关键字
async
函数是一种特殊的函数,它能以同步代码的方式编写异步代码。在async
函数内部,可以使用await
表达式来等待一个异步操作返回一个Promise对象。这种方式可以让异步代码的编写和阅读更接近同步代码的风格,提高代码的可读性和可维护性。
// 定义一个async函数 async function myAsyncFunction() { // 使用await等待异步操作完成 const result = await someAsyncOperation(); console.log(result); }
async函数和await关键字有什么区别?
async
和 await
是 JavaScript 中用于异步编程的两个关键字,它们共同工作以简化异步代码的编写和理解,但它们各自有不同的用途和含义:
async 关键字
async
是一个用于声明异步函数的关键字。- 任何使用
async
声明的函数都会自动返回一个Promise
对象。 - 如果函数正常执行结束,
Promise
将被解决(resolve)并返回函数的返回值。 - 如果函数中抛出错误,
Promise
将被拒绝(reject)。 async
函数内部可以包含一个或多个await
表达式。
await 关键字
await
是一个用于等待一个Promise
对象解决(resolve)的关键字。await
只能在async
函数内部使用。- 当执行到
await
表达式时,JavaScript 引擎会暂停该async
函数的执行,直到等待的Promise
被解决。 - 如果
Promise
被解决,await
表达式返回Promise
的值。 - 如果
Promise
被拒绝,await
表达式会抛出拒绝的原因,这可以通过try...catch
语句捕获。 await
后面通常跟的是一个异步操作,比如一个返回Promise
的函数调用。
它们的区别
async
是用来声明函数的,而await
是用来在函数内部等待异步操作的。async
本身不暂停代码执行,它只是让函数返回一个Promise
;而await
是用来暂停代码执行,直到Promise
被解决。async
可以不与await
一起使用,这时函数仍然返回一个Promise
,但不会暂停执行。await
必须用在async
函数内部,否则会抛出语法错误。
示例
// async 函数声明 async function fetchData() { // 等待异步操作完成 const data = await fetchSomeData(); // 这里使用了 await return data; } // 单独使用 async async function justAsync() { console.log('This is an async function, but without await.'); } // 使用 await async function useAwait() { console.log('Before await.'); await justAsync(); // 等待 justAsync 完成 console.log('After await.'); }
所以啊, V哥提醒一下,async
和 await
是异步编程中两个互补的概念,async
用于声明异步函数,而 await
用于在异步函数内部等待异步操作的完成,初学者需要注意不要混淆了。
2. 使用Promise对象
上面我们已经提到Promise对象了,Promise是处理异步操作的对象,它提供了一个状态机制来管理异步操作的不同阶段,代表一个异步操作的最终完成(或失败)及其结果值,并提供了一些方法来注册回调函数以处理异步操作的成功或失败的结果。Promise有三种状态:pending(进行中)、fulfilled(已完成)和rejected(已拒绝)。
// 创建一个新的Promise const myPromise = new Promise((resolve, reject) => { // 异步操作 if (/* 异步操作成功 */) { resolve("Success"); } else { reject("Error"); } }); // 使用then和catch处理Promise的结果 myPromise.then((value) => { console.log(value); // "Success" }).catch((error) => { console.error(error); // "Error" });
3. 异常处理
在异步函数中,如果出现错误,可以通过try...catch
语句来捕获异常。
async function myAsyncFunction() { try { const result = await someAsyncOperation(); console.log(result); } catch (error) { console.error(error); } }
4. 并发执行异步任务
可以使用Promise.all
来并发执行多个异步任务,并等待它们全部完成。
async function concurrentTasks() { const [result1, result2] = await Promise.all([ asyncOperation1(), asyncOperation2() ]); console.log(result1, result2); }
5. 使用Actor模型
ArkTS语言采用的Actor模型是一种并发编程模型,其中每个Actor都是一个独立的计算单元,拥有自己的状态和行为,并通过消息传递与其他Actor进行通信和协作。
1. Actor模型概述
在Actor模型中,每个Actor都可以接收异步消息,并根据消息内容和当前状态做出响应。Actor之间的消息传递是异步的,发送消息的Actor不需要等待接收消息的Actor的响应,从而实现并发执行。由于每个Actor都是独立的,它们之间不存在共享状态,因此不需要进行锁机制和同步操作,避免了一些常见的并发编程问题,如死锁和竞争条件。
2. 数据传输对象
ArkTS语言支持传输的数据对象可以分为四种:普通对象、可转移对象、可共享对象和Native绑定对象。普通对象的传输是通过结构化克隆算法进行序列化的,支持多种类型,包括基础类型、Date、String、RegExp、Array、Map、Set等。
3. 实现例子
以下是一个使用ArkTS的Actor模型实现的生产者消费者问题的示例:
生产者(Producer)和消费者(Consumer)的Actor模型实现:
import taskpool from '@ohos.taskpool'; // 跨线程并发任务 @Concurrent async function produce(): Promise<number>{ // 添加生产相关逻辑 console.log("test producing..."); return Math.random(); } class Consumer { public consume(value: number) { // 添加消费相关逻辑 console.log("test consuming value: " + value); } } @Entry @Component struct Index { @State message: string = 'Hello I am VG'; build() { Row() { Column() { Text(this.message) .fontSize(50) .fontWeight(FontWeight.Bold) Button() { Text("start") }.onClick(() => { let produceTask: taskpool.Task = new taskpool.Task(produce); let consumer: Consumer = new Consumer(); for (let index: number = 0; index < 10; index++) { // 执行生产异步并发任务 taskpool.execute(produceTask).then((res: number) => { consumer.consume(res); }).catch((e: Error) => { console.error(e.message); }) } }) .width('20%') .height('20%') } .width('100%') } .height('100%') } }
在这个例子中,produce
函数是一个异步函数,模拟生产者的生产过程,并返回一个随机数作为产品。Consumer
类包含 consume
方法,用于消费产品。在UI界面上,当用户点击“start”按钮时,会启动10次生产任务,每次生产任务完成后,都会调用Consumer
的consume
方法来消费产品。
这个例子展示了如何在ArkTS中使用Actor模型来实现并发执行,其中生产者和消费者之间通过异步消息传递来通信,无需等待对方的响应,从而实现高效的并发处理。
最后
ArkTS提供了强大的异步编程能力,使得开发者可以有效地处理异步任务,提高程序的性能和响应能力。对于有 TypeScript 经验的兄弟是不是有种找到真爱的感觉呢。关注威哥爱编程,鸿蒙开天辟地,你我皆是同路人。