一、并发概述
并发是指在同一时间内,存在多个任务同时执行的情况。对于多核设备,这些任务可能同时在不同CPU上并行执行。对于单核设备,多个并发任务不会在同一时刻并行执行,但是CPU会在某个任务休眠或进行I/O操作等状态下切换任务,调度执行其他任务,提升CPU的资源利用率。
为了提升应用的响应速度与帧率,避免耗时任务对UI主线程的影响,ArkTS提供了异步并发和多线程并发两种处理策略。
并发多线程场景下,不同并发线程间需要进行数据通信,不同类别对象的传输方式存在差异,包括拷贝或内存共享等。
并发能力在多种场景中都有应用,其中包括异步并发任务、耗时任务(CPU密集型任务、I/O密集型任务和同步任务等)、长时任务、常驻任务等。开发者可以根据不同的任务诉求和场景,选择相应的并发策略进行优化和开发,也可以具体查看应用多线程开发实践案例。
二、异步并发 (Promise和async/await)
Promise和async/await提供异步并发能力,是标准的JS异步语法。异步代码会被挂起并在之后继续执行,同一时间只有一段代码执行,适用于单次I/O任务的场景开发,例如一次网络请求、一次文件读写等操作。无需另外启动线程执行。
异步语法是一种编程语言的特性,允许程序在执行某些操作时不必等待其完成,而是可以继续执行其他操作。
三、Promise
Promise是一种用于处理异步操作的对象,可以将异步操作转换为类似于同步操作的风格,以方便代码编写和维护。Promise提供了一个状态机制来管理异步操作的不同阶段,并提供了一些方法来注册回调函数以处理异步操作的成功或失败的结果。
Promise有三种状态:pending(进行中)、fulfilled(已完成)和rejected(已拒绝)。Promise对象创建后处于pending状态,并在异步操作完成后转换为fulfilled或rejected状态。
最基本的用法是通过构造函数实例化一个Promise对象,同时传入一个带有两个参数的函数,通常称为executor函数。executor函数接收两个参数:resolve和reject,分别表示异步操作成功和失败时的回调函数。例如,以下代码创建了一个Promise对象并模拟了一个异步操作:
const promise: Promise<number> = new Promise((resolve: Function, reject: Function) => {
setTimeout(() => {
const randomNumber: number = Math.random();
if (randomNumber > 0.5) {
resolve(randomNumber);
} else {
reject(new Error('Random number is too small'));
}
}, 1000);
})
上述代码中,setTimeout函数模拟了一个异步操作,并在1秒钟后随机生成一个数字。如果随机数大于0.5,则执行resolve回调函数并将随机数作为参数传递;否则执行reject回调函数并传递一个错误对象作为参数。
Promise对象创建后,可以使用then方法和catch方法指定fulfilled状态和rejected状态的回调函数。then方法可接受两个参数,一个处理fulfilled状态的函数,另一个处理rejected状态的函数。只传一个参数则表示当Promise对象状态变为fulfilled时,then方法会自动调用这个回调函数,并将Promise对象的结果作为参数传递给它。使用catch方法注册一个回调函数,用于处理“失败”的结果,即捕获Promise的状态改变为rejected状态或操作失败抛出的异常。例如:
import { BusinessError } from '@kit.BasicServicesKit';
promise.then((result: number) => {
console.info(`Random number is ${result}`);
}).catch((error: BusinessError) => {
console.error(error.message);
});
上述代码中,then方法的回调函数接收Promise对象的成功结果作为参数,并将其输出到控制台上。如果Promise对象进入rejected状态,则catch方法的回调函数接收错误对象作为参数,并将其输出到控制台上。
效果图
四、async/await
async/await是一种用于处理异步操作的Promise语法糖,使得编写异步代码变得更加简单和易读。通过使用async关键字声明一个函数为异步函数,并使用await关键字等待Promise的解析(完成或拒绝),以同步的方式编写异步操作的代码。
async函数是一个返回Promise对象的函数,用于表示一个异步操作。在async函数内部,可以使用await关键字等待一个Promise对象的解析,并返回其解析值。如果一个async函数抛出异常,那么该函数返回的Promise对象将被拒绝,并且异常信息会被传递给Promise对象的onRejected()方法。
下面是一个使用async/await的例子,其中模拟了一个以同步方式执行异步操作的场景,该操作会在3秒钟后返回一个字符串。
async function myAsyncFunction(): Promise<string> {
const result: string = await new Promise((resolve: Function) => {
setTimeout(() => {
resolve('Hello, world!');
}, 3000);
});
console.info(result); // 输出: Hello, world!
return result;
}
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.onClick(async () => {
let res = await myAsyncFunction();
console.info("res is: " + res);
})
}
.width('100%')
}
.height('100%')
}
}
效果图
在上述示例代码中,使用了await关键字来等待Promise对象的解析,并将其解析值存储在result变量中。
需要注意的是,由于要等待异步操作完成,因此需要将整个操作包在async函数中,并搭配await关键字使用。除了在async函数中使用await外,还可以使用try/catch块来捕获异步操作中的异常。
async function myAsyncFunction(): Promise<void> {
try {
const result: string = await new Promise((resolve: Function) => {
resolve('Hello, world!');
});
} catch (e) {
console.error(`Get exception: ${e}`);
}
}
myAsyncFunction();
五、异步并发 (Promise和async/await)示例完整代码
TestPromiseAsyncAwait.ets
import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';
const TAG: string = 'TestPromiseAsyncAwait';
const DOMAIN_NUMBER: number = 0xFF00;
// 异步并发 (Promise和async/await) https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/async-concurrency-overview-V5
function testPromise() {
const promise: Promise<number> = new Promise((resolve: Function, reject: Function) => {
setTimeout(() => {
const randomNumber: number = Math.random();
if (randomNumber > 0.5) {
resolve(randomNumber);
} else {
reject(new Error('Random number is too small'));
}
}, 1000);
})
promise.then((result: number) => {
console.info(`promise.then Random number is ${result}`);
}).catch((error: BusinessError) => {
console.error(error.message);
});
}
async function myAsyncFunction(): Promise<string> {
const result: string = await new Promise((resolve: Function) => {
setTimeout(() => {
resolve('Hello, world!');
}, 3000);
});
console.info(result); // 输出: Hello, world!
return result;
}
async function myAsyncFunction2(): Promise<void> {
try {
const result: string = await new Promise((resolve: Function) => {
resolve('Hello, world!');
});
} catch (e) {
console.error(`Get exception: ${e}`);
}
}
myAsyncFunction();
@Entry
@Component
struct TestPromiseAsyncAwait {
build() {
Column() {
Button('测试Promise')
.fontColor(Color.Black)
.fontWeight(FontWeight.Normal)
.fontSize(16)
.margin({ top: 20 })
.onClick((event: ClickEvent) => {
testPromise()
})
Button('测试async/await ')
.fontColor(Color.Black)
.fontWeight(FontWeight.Normal)
.fontSize(16)
.margin({ top: 20 })
.onClick((event: ClickEvent) => {
let result = myAsyncFunction();
console.log(`myAsyncFunction result is ${result}`);
// myAsyncFunction2();
})
}
.height('100%')
.width('100%')
}
}
标签:异步,并发,await,HarmonyOS,Promise,result,async
From: https://blog.csdn.net/ChinaDragon10/article/details/144083934