• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Asynchronous Concurrency (Promise and Async/Await)
2
3
4Promise and async/await are standard JavaScript asynchronous syntax that provides asynchronous concurrency capabilities. Asynchronous code is suspended and continues to execute later, ensuring that only one piece of code is executed at any given moment. The following are typical scenarios of asynchronous concurrency:
5
6- Non-blocking I/O operations: network requests, file reading and writing, and timers.
7
8- Lightweight tasks without CPU blocking: tasks with short execution times.
9
10- Clear logical dependencies: tasks with explicit order or parallel relationships.
11
12Asynchronous concurrency is a feature of programming languages that allows programs to continue executing other operations without waiting for certain operations to complete.
13
14## Promise
15
16A Promise is an object used to process asynchronous operations. It converts asynchronous operations into a style similar to synchronous operations for easier code writing and maintenance. A Promise provides a state mechanism to manage different phases of asynchronous operations. There are three states for a Promise: pending (in progress), fulfilled (completed, also called resolved), and rejected (failed). After creation, a Promise is in the pending state and transitions to the fulfilled or rejected state upon completion of the asynchronous operation.
17
18Promises offer **then** and **catch** methods to register callback functions for handling the success or failure of asynchronous operations. Changes in the Promise state trigger callbacks to be added to the microtask queue, awaiting execution. These callbacks rely on the event loop mechanism, which prioritizes microtasks after macro tasks have completed, ensuring asynchronous scheduling of callbacks.
19
20The most basic usage involves instantiating a Promise object through its constructor, passing in a function (usually named **executor**) with two parameters. The two parameters are **resolve** and **reject**, which represent the callback functions for the success and failure of the asynchronous operation, respectively. For example, the code snippet below creates a Promise object and simulates an asynchronous operation:
21
22```ts
23const promise: Promise<number> = new Promise((resolve: Function, reject: Function) => {
24  setTimeout(() => {
25    const randomNumber: number = Math.random();
26    if (randomNumber > 0.5) {
27      resolve(randomNumber);
28    } else {
29      reject(new Error('Random number is too small'));
30    }
31  }, 1000);
32})
33```
34<!-- @[promise_async_operation](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTs/ArkTsConcurrent/AsyncConcurrencyOverview/entry/src/main/ets/pages/Index.ets) -->
35
36In the above code, the **setTimeout** function simulates an asynchronous operation and generates a random number after 1 second. If the random number is greater than 0.5, the **resolve** callback is invoked with the random number; otherwise, the **reject** callback is invoked with an error object.
37
38After a Promise object is created, you can use the **then** and **catch** methods to specify callback functions for the fulfilled and rejected states. The **then** method can accept two parameters: one for handling the fulfilled state and the other for handling the rejected state. If only one parameter is passed in, the **then** method automatically calls the callback function when the Promise object state changes to **fulfilled**, with the result of the Promise object passed as a parameter. The **catch** method receives a callback function to handle failures, that is, capturing the Promise's transition to the rejected state or any exceptions thrown during the operation. The code snippet below shows the use of the **then** and **catch** methods.
39
40```ts
41import { BusinessError } from '@kit.BasicServicesKit';
42
43// Use the then method to define success and failure callbacks.
44promise.then((result: number) => {
45  console.info(`The number for success is ${result}`); // Executed on success.
46}, (error: BusinessError) => {
47  console.error(error.message); // Executed on failure.
48}
49);
50
51// Use the then method to define a success callback and the catch method to define a failure callback.
52promise.then((result: number) => {
53  console.info(`Random number is ${result}`); // Executed on success.
54}).catch((error: BusinessError) => {
55  console.error(error.message); // Executed on failure.
56});
57```
58<!-- @[promise_then_catch_handling](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTs/ArkTsConcurrent/AsyncConcurrencyOverview/entry/src/main/ets/pages/Index.ets) -->
59
60In this example, the callback function of the **then** method receives the successful result of the Promise object as a parameter and outputs it to the console. If the Promise object enters the rejected state, the callback function of the **catch** method receives the error object as a parameter and outputs it to the console.
61
62> **NOTE**
63>
64> When a Promise object is rejected and not handled by the **catch** method, it triggers the **unhandledRejection** event. You can use the [errorManager.on('unhandledrejection')](../reference/apis-ability-kit/js-apis-app-ability-errorManager.md#errormanageroffunhandledrejection12) interface to listen for this event and globally capture unhandled Promise rejects.
65
66## Async/Await
67
68Async/Await is syntactic sugar for handling asynchronous operations with Promises, making it easier and more readable to write asynchronous code. By declaring a function as asynchronous with the **async** keyword and using the **await** keyword to wait for the resolution of a Promise (fulfilled or rejected), you can write asynchronous operations in a synchronous style.
69
70An **async** function implements asynchronous operations by returning a Promise object. It can contain zero or more **await** keywords, pausing execution until the associated Promise completes its state transition (fulfilled/rejected). If an exception is thrown during function execution, the exception directly triggers the returned Promise to enter the rejected state, and the error object can be captured using the **.catch()** method or the second callback parameter of **then**.
71
72The code snippet below uses async/await to simulate an asynchronous operation that returns a string after 3 seconds.
73
74```ts
75async function myAsyncFunction(): Promise<string> {
76  const result: string = await new Promise((resolve: Function) => {
77    setTimeout(() => {
78      resolve('Hello, world!');
79    }, 3000);
80  });
81  console.info(result); // Output: Hello, world!
82  return result;
83}
84
85@Entry
86@Component
87struct Index {
88  @State message: string = 'Hello World';
89  build() {
90    Row() {
91      Column() {
92        Text(this.message)
93          .fontSize(50)
94          .fontWeight(FontWeight.Bold)
95          .onClick(async () => {
96            let res = await myAsyncFunction();
97            console.info('res is: ' + res);
98          })
99      }
100      .width('100%')
101    }
102    .height('100%')
103  }
104}
105```
106<!-- @[async_await_sync_operation](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTs/ArkTsConcurrent/AsyncConcurrencyOverview/entry/src/main/ets/pages/Index.ets) -->
107
108In this code, the await keyword is used to wait for the resolution of the Promise object and store its resolved value in the **result** variable.
109
110Note that when waiting for asynchronous operations, the entire operation should be wrapped in an **async** function and used with **await**. You can also use **try/catch** blocks to catch exceptions in asynchronous operations.
111
112```ts
113async function myAsyncFunction(): Promise<void> {
114  try {
115    const result: string = await new Promise((resolve: Function) => {
116      resolve('Hello, world!');
117    });
118  } catch (e) {
119    console.error(`Get exception: ${e}`);
120  }
121}
122
123myAsyncFunction();
124```
125<!-- @[async_operation_error_handling_with_try_catch](https://gitee.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTs/ArkTsConcurrent/AsyncConcurrencyOverview/entry/src/main/ets/pages/Index.ets) -->
126
127<!--no_check-->