1# \@Concurrent Decorator: Declaring and Verifying Concurrent Functions 2 3To pass function verification, the concurrent functions executed in a [TaskPool](../reference/apis-arkts/js-apis-taskpool.md) must be decorated using \@Concurrent. 4 5 6> **NOTE** 7> 8> Since API version 9, the @Concurrent decorator can be used to declare and verify concurrent functions. 9 10 11## Decorator Description 12| \@Concurrent Decorator| Description | 13| --------------------- | ------------------------------------------------------------------------------------------ | 14| Decorator parameters | None. | 15| Application scenarios | This decorator can be used only in projects of the stage model. It can be used only in .ets files. | 16| Decorated function types | This decorator can be used for asynchronous functions and common functions. It cannot be used for generators, arrow functions, or methods. It does not support class member functions or anonymous functions. | 17| Variable types in decorated functions | Local variables, input parameters, and variables imported through **import** are supported. Closure variables are not allowed. | 18| Return value types in decorated functions | For details about the supported return value types, see [Serialization Types Supported by TaskPool and Worker](serialization-support-types.md). | 19 20> **NOTE** 21> 22> Pay attention to the performance of returning Promise in the concurrent function. The concurrent synchronous function processes and returns Promise with the result. 23 24**Example** 25 26```ts 27import { taskpool } from '@kit.ArkTS'; 28 29@Concurrent 30function testPromise(args1: number, args2: number): Promise<number> { 31 return new Promise<number>((testFuncA, testFuncB)=>{ 32 testFuncA(args1 + args2); 33 }); 34} 35 36@Concurrent 37async function testPromise1(args1: number, args2: number): Promise<number> { 38 return new Promise<number>((testFuncA, testFuncB)=>{ 39 testFuncA(args1 + args2); 40 }); 41} 42 43@Concurrent 44async function testPromise2(args1: number, args2: number): Promise<number> { 45 return await new Promise<number>((testFuncA, testFuncB)=>{ 46 testFuncA(args1 + args2) 47 }); 48} 49 50@Concurrent 51function testPromise3() { 52 return Promise.resolve(1); 53} 54 55@Concurrent 56async function testPromise4(): Promise<number> { 57 return 1; 58} 59 60@Concurrent 61async function testPromise5(): Promise<string> { 62 return await new Promise((resolve) => { 63 setTimeout(()=>{ 64 resolve("Promise setTimeout after resolve"); 65 }, 1000) 66 }); 67} 68 69async function testConcurrentFunc() { 70 let task1: taskpool.Task = new taskpool.Task(testPromise, 1, 2); 71 let task2: taskpool.Task = new taskpool.Task(testPromise1, 1, 2); 72 let task3: taskpool.Task = new taskpool.Task(testPromise2, 1, 2); 73 let task4: taskpool.Task = new taskpool.Task(testPromise3); 74 let task5: taskpool.Task = new taskpool.Task(testPromise4); 75 let task6: taskpool.Task = new taskpool.Task(testPromise5); 76 77 taskpool.execute(task1).then((d:object)=>{ 78 console.info("task1 res is: " + d) 79 }).catch((e:object)=>{ 80 console.info("task1 catch e: " + e) 81 }) 82 taskpool.execute(task2).then((d:object)=>{ 83 console.info("task2 res is: " + d) 84 }).catch((e:object)=>{ 85 console.info("task2 catch e: " + e) 86 }) 87 taskpool.execute(task3).then((d:object)=>{ 88 console.info("task3 res is: " + d) 89 }).catch((e:object)=>{ 90 console.info("task3 catch e: " + e) 91 }) 92 taskpool.execute(task4).then((d:object)=>{ 93 console.info("task4 res is: " + d) 94 }).catch((e:object)=>{ 95 console.info("task4 catch e: " + e) 96 }) 97 taskpool.execute(task5).then((d:object)=>{ 98 console.info("task5 res is: " + d) 99 }).catch((e:object)=>{ 100 console.info("task5 catch e: " + e) 101 }) 102 taskpool.execute(task6).then((d:object)=>{ 103 console.info("task6 res is: " + d) 104 }).catch((e:object)=>{ 105 console.info("task6 catch e: " + e) 106 }) 107} 108 109testConcurrentFunc(); 110``` 111 112The output is as follows: 113``` 114task1 res is: 3 115task2 catch e: Error: Can't return Promise in pending state 116task3 res is: 3 117task4 res is: 1 118task5 res is: 1 119task6 res is: Promise setTimeout after resolve 120``` 121 122> **NOTE** 123> 124> If Promise is used in the concurrent asynchronous function, you are advised to use await to capture exceptions that may occur in Promise. A recommended example is provided below. 125 126**Example** 127 128```ts 129@Concurrent 130async function testPromiseError() { 131 await new Promise<number>((resolve, reject) => { 132 resolve(1); 133 }).then(()=>{ 134 throw new Error("testPromise Error"); 135 }) 136} 137 138@Concurrent 139async function testPromiseError1() { 140 await new Promise<string>((resolve, reject) => { 141 reject("testPromiseError1 Error msg"); 142 }) 143} 144 145@Concurrent 146function testPromiseError2() { 147 return new Promise<string>((resolve, reject) => { 148 reject("testPromiseError2 Error msg"); 149 }) 150} 151 152async function testConcurrentFunc() { 153 let task1: taskpool.Task = new taskpool.Task(testPromiseError); 154 let task2: taskpool.Task = new taskpool.Task(testPromiseError1); 155 let task3: taskpool.Task = new taskpool.Task(testPromiseError2); 156 157 taskpool.execute(task1).then((d:object)=>{ 158 console.info("task1 res is: " + d) 159 }).catch((e:object)=>{ 160 console.info("task1 catch e: " + e) 161 }) 162 taskpool.execute(task2).then((d:object)=>{ 163 console.info("task2 res is: " + d) 164 }).catch((e:object)=>{ 165 console.info("task2 catch e: " + e) 166 }) 167 taskpool.execute(task3).then((d:object)=>{ 168 console.info("task3 res is: " + d) 169 }).catch((e:object)=>{ 170 console.info("task3 catch e: " + e) 171 }) 172} 173 174testConcurrentFunc() 175``` 176 177The output is as follows: 178``` 179task1 catch e: Error: testPromise Error 180task2 catch e: testPromiseError1 Error msg 181task3 catch e: testPromiseError2 Error msg 182``` 183 184 185## Example 186 ```ts 187 import { taskpool } from '@kit.ArkTS'; 188 189 @Concurrent 190 function add(num1: number, num2: number): number { 191 return num1 + num2; 192 } 193 194 async function ConcurrentFunc(): Promise<void> { 195 try { 196 let task: taskpool.Task = new taskpool.Task(add, 1, 2); 197 console.info("taskpool res is: " + await taskpool.execute(task)); 198 } catch (e) { 199 console.error("taskpool execute error is: " + e); 200 } 201 } 202 203 @Entry 204 @Component 205 struct Index { 206 @State message: string = 'Hello World' 207 208 build() { 209 Row() { 210 Column() { 211 Text(this.message) 212 .fontSize(50) 213 .fontWeight(FontWeight.Bold) 214 .onClick(() => { 215 ConcurrentFunc(); 216 }) 217 } 218 .width('100%') 219 } 220 .height('100%') 221 } 222 } 223 ``` 224