• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)-->