1# 异步并发 (Promise和async/await) 2 3 4Promise和async/await提供异步并发能力,是标准的JS异步语法。异步代码会被挂起并在之后继续执行,同一时间只有一段代码执行,适用于单次I/O任务的场景开发,例如一次网络请求、一次文件读写等操作。无需另外启动线程执行。 5 6异步语法是一种编程语言的特性,允许程序在执行某些操作时不必等待其完成,而是可以继续执行其他操作。 7 8## 验证代码拼接 9 10代码拼接 11 12```ts 13// [Start promise_then_catch_handling] 14import { BusinessError } from '@kit.BasicServicesKit'; 15 16// [Start promise_async_operation] 17const promise: Promise<number> = new Promise((resolve: Function, reject: Function) => { 18 setTimeout(() => { 19 const randomNumber: number = Math.random(); 20 if (randomNumber > 0.5) { 21 resolve(randomNumber); 22 } else { 23 reject(new Error('Random number is too small')); 24 } 25 }, 1000); 26}) 27// [End promise_async_operation] 28 29promise.then((result: number) => { 30 console.info(`Random number is ${result}`); 31}).catch((error: BusinessError) => { 32 console.error(error.message); 33}); 34// [End promise_then_catch_handling] 35``` 36 37 38## 验证代码嵌套 39 40代码嵌套 41 42```ts 43``` 44 45## docs代码和sample中不一致(空行),验证扫描结果 46 47docs代码和sample中不一致(空行),验证扫描结果 48 49```ts 50const promise: Promise<number> = new Promise((resolve: Function, reject: Function) => { 51 setTimeout(() => { 52 const randomNumber: number = Math.random(); 53 if (randomNumber > 0.5) { 54 resolve(randomNumber); 55 } else { 56 reject(new Error('Random number is too small')); 57 } 58 }, 1000); 59 60}) 61``` 62<!--@[promise_async_operation](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTs/ArkTsConcurrent/AsyncConcurrencyOverview/entry/src/main/ets/pages/Index.ets)--> 63 64## docs代码和sample中不一致(单行缩进不一致),验证扫描结果 65 66docs代码和sample中不一致(单行缩进不一致),验证扫描结果 67 68```ts 69import { BusinessError } from '@kit.BasicServicesKit'; 70 71// [Start promise_async_operation] 72const promise: Promise<number> = new Promise((resolve: Function, reject: Function) => { 73 setTimeout(() => { 74 const randomNumber: number = Math.random(); 75 if (randomNumber > 0.5) { 76 resolve(randomNumber); 77 } else { 78 reject(new Error('Random number is too small')); 79 } 80 }, 1000); 81}) 82// [End promise_async_operation] 83 84promise.then((result: number) => { 85 console.info(`Random number is ${result}`); 86}).catch((error: BusinessError) => { 87 console.error(error.message); 88}); 89``` 90<!--@[promise_then_catch_handling](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTs/ArkTsConcurrent/AsyncConcurrencyOverview/entry/src/main/ets/pages/Index.ets)--> 91 92 93## docs代码和sample中不一致(整段代码缩进不一致),验证扫描结果 94 95docs代码和sample中不一致(整段代码缩进不一致),验证扫描结果 96 97* list 1 98 ```ts 99 async function myAsyncFunction(): Promise<string> { 100 const result: string = await new Promise((resolve: Function) => { 101 setTimeout(() => { 102 resolve('Hello, world!'); 103 }, 3000); 104 }); 105 console.info(result); // 输出: Hello, world! 106 return result; 107 } 108 109 @Entry 110 @Component 111 struct PromiseAsyncAwait { 112 @State message: string = 'Hello World'; 113 114 build() { 115 Row() { 116 Column() { 117 Text(this.message) 118 .fontSize(50) 119 .fontWeight(FontWeight.Bold) 120 .onClick(async () => { 121 let res = await myAsyncFunction(); 122 console.info('res is: ' + res); 123 }) 124 } 125 .width('100%') 126 } 127 .height('100%') 128 } 129 } 130 ``` 131 <!--@[async_await_sync_operation](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTs/ArkTsConcurrent/AsyncConcurrencyOverview/entry/src/main/ets/pages/Index.ets)--> 132* list 2 133* list 3 134 135## Promise 136 137Promise是一种用于处理异步操作的对象,可以将异步操作转换为类似于同步操作的风格,以方便代码编写和维护。Promise提供了一个状态机制来管理异步操作的不同阶段,并提供了一些方法来注册回调函数以处理异步操作的成功或失败的结果。 138 139Promise有三种状态:pending(进行中)、fulfilled(已完成)和rejected(已拒绝)。Promise对象创建后处于pending状态,并在异步操作完成后转换为fulfilled或rejected状态。 140 141最基本的用法是通过构造函数实例化一个Promise对象,同时传入一个带有两个参数的函数,通常称为executor函数。executor函数接收两个参数:resolve和reject,分别表示异步操作成功和失败时的回调函数。例如,以下代码创建了一个Promise对象并模拟了一个异步操作: 142 143```ts 144const promise: Promise<number> = new Promise((resolve: Function, reject: Function) => { 145 setTimeout(() => { 146 const randomNumber: number = Math.random(); 147 if (randomNumber > 0.5) { 148 resolve(randomNumber); 149 } else { 150 reject(new Error('Random number is too small')); 151 } 152 }, 1000); 153}) 154``` 155<!--@[promise_async_operation](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTs/ArkTsConcurrent/AsyncConcurrencyOverview/entry/src/main/ets/pages/Index.ets)--> 156 157上述代码中,setTimeout函数模拟了一个异步操作,并在1秒钟后随机生成一个数字。如果随机数大于0.5,则执行resolve回调函数并将随机数作为参数传递;否则执行reject回调函数并传递一个错误对象作为参数。 158 159Promise对象创建后,可以使用then方法和catch方法指定fulfilled状态和rejected状态的回调函数。then方法可接受两个参数,一个处理fulfilled状态的函数,另一个处理rejected状态的函数。只传一个参数则表示当Promise对象状态变为fulfilled时,then方法会自动调用这个回调函数,并将Promise对象的结果作为参数传递给它。使用catch方法注册一个回调函数,用于处理“失败”的结果,即捕获Promise的状态改变为rejected状态或操作失败抛出的异常。例如: 160 161```ts 162import { BusinessError } from '@kit.BasicServicesKit'; 163 164promise.then((result: number) => { 165 console.info(`Random number is ${result}`); 166}).catch((error: BusinessError) => { 167 console.error(error.message); 168}); 169``` 170<!--@[promise_then_catch_handling](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTs/ArkTsConcurrent/AsyncConcurrencyOverview/entry/src/main/ets/pages/Index.ets)--> 171 172上述代码中,then方法的回调函数接收Promise对象的成功结果作为参数,并将其输出到控制台上。如果Promise对象进入rejected状态,则catch方法的回调函数接收错误对象作为参数,并将其输出到控制台上。 173 174> **说明:** 175> 176> 当Promise被reject且未通过catch方法来处理时,会触发unhandledrejection事件。可使用errorManager.on('error')接口监听该事件,以全局捕获未处理的Promise reject。 177 178## async/await 179 180async/await是一种用于处理异步操作的Promise语法糖,使得编写异步代码变得更加简单和易读。通过使用async关键字声明一个函数为异步函数,并使用await关键字等待Promise的解析(完成或拒绝),以同步的方式编写异步操作的代码。 181 182async函数是一个返回Promise对象的函数,用于表示一个异步操作。在async函数内部,可以使用await关键字等待一个Promise对象的解析,并返回其解析值。如果一个async函数抛出异常,那么该函数返回的Promise对象将被拒绝,并且异常信息会被传递给Promise对象的onRejected()方法。 183 184下面是一个使用async/await的例子,其中模拟了一个以同步方式执行异步操作的场景,该操作会在3秒钟后返回一个字符串。 185 186```ts 187async function myAsyncFunction(): Promise<string> { 188 const result: string = await new Promise((resolve: Function) => { 189 setTimeout(() => { 190 resolve('Hello, world!'); 191 }, 3000); 192 }); 193 console.info(result); // 输出: Hello, world! 194 return result; 195} 196 197@Entry 198@Component 199struct Index { 200 @State message: string = 'Hello World'; 201 202 build() { 203 Row() { 204 Column() { 205 Text(this.message) 206 .fontSize(50) 207 .fontWeight(FontWeight.Bold) 208 .onClick(async () => { 209 let res = await myAsyncFunction(); 210 console.info("res is: " + res); 211 }) 212 } 213 .width('100%') 214 } 215 .height('100%') 216 } 217} 218``` 219<!--@[async_await_sync_operation](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTs/ArkTsConcurrent/AsyncConcurrencyOverview/entry/src/main/ets/pages/Index.ets)--> 220 221上述代码中,sample含有Exclude代码 222 223在上述示例代码中,使用了await关键字来等待Promise对象的解析,并将其解析值存储在result变量中。 224 225需要注意的是,由于要等待异步操作完成,因此需要将整个操作包在async函数中,并搭配await关键字使用。除了在async函数中使用await外,还可以使用try/catch块来捕获异步操作中的异常。 226 227```ts 228async function myAsyncFunction(): Promise<void> { 229 try { 230 const result: string = await new Promise((resolve: Function) => { 231 resolve('Hello, world!'); 232 }); 233 } catch (e) { 234 console.error(`Get exception: ${e}`); 235 } 236} 237 238myAsyncFunction(); 239``` 240<!--@[async_operation_error_handling_with_try_catch](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTs/ArkTsConcurrent/AsyncConcurrencyOverview/entry/src/main/ets/pages/Index.ets)--> 241 242## 验证注释格式不同 243 244验证注释格式不同 245```ts 246import { taskpool } from '@kit.ArkTS'; 247 248// 跨线程并发任务 249@Concurrent 250async function produce(): Promise<number> { 251 /* 252 * 添加生产相关逻辑 253 */ 254 console.info("producing..."); 255 return Math.random(); 256} 257 258class Consumer { 259 public consume(value: Object) { 260 console.info("consuming value: " + value); // 添加消费相关逻辑 261 } 262} 263 264@Entry 265@Component 266struct Index { 267 @State message: string = 'Hello World' 268 269 build() { 270 Row() { 271 Column() { 272 Text(this.message) 273 .fontSize(50) 274 .fontWeight(FontWeight.Bold) 275 Button() { 276 Text("start") 277 }.onClick(() => { 278 let produceTask: taskpool.Task = new taskpool.Task(produce); 279 let consumer: Consumer = new Consumer(); 280 for (let index: number = 0; index < 10; index++) { 281 // 执行生产异步并发任务,执行生产异步并发任务 282 taskpool.execute(produceTask).then((res: Object) => { 283 consumer.consume(res); 284 }).catch((e: Error) => { 285 console.error(e.message); 286 }) 287 } 288 }) 289 .width('20%') 290 .height('20%') 291 } 292 .width('100%') 293 } 294 .height('100%') 295 } 296} 297``` 298<!--@[actor_model](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTs/ArkTsConcurrent/MultithreadedConcurrency/MultiThreadConcurrencyOverview/entry/src/main/ets/pages/Index.ets)-->