1# Concurrent Loading of Service Modules
2
3During app startup, multiple service modules need to be loaded. For example, if different modules of a map app, such as positioning, taxi hailing, and navigation, are all initialized in the UI main thread, the cold start time will be greatly affected. In this case, the functions of these modules need to be loaded in different sub-threads in parallel to reduce the startup time.
4
5The TaskPool capability provided by ArkTS can be used to move different service initialization tasks to subthreads. Service modules can be implemented as [NativeBinding object](transferabled-object.md) by sinking C++, or [Sendable object](arkts-sendable.md) can be defined at the ArkTS layer. The initialized module can be returned to the UI main thread for calling. The implementation is as follows:
6
71. Definition of each service function (SDK) module (The Sendable object is used as an example.)
8   The calculator service module is defined as follows:
9
10   ```ts
11   // sdk/Calculator.ets
12   import { collections } from '@kit.ArkTS'
13
14   @Sendable
15   export class Calculator {
16     history?: collections.Array<collections.Array<string>>
17     totalCount: number = 0
18
19     static init(): Calculator {
20       let calc = new Calculator()
21       calc.totalCount = 0
22       calc.history = collections.Array.create(calc.totalCount, collections.Array.create(2, ""));
23       return calc
24     }
25
26     add(a: number, b: number) {
27       let result = a + b;
28       this.newCalc(`${a} + ${b}`, `${result}`);
29       return result
30     }
31
32     sub(a: number, b: number) {
33       let result = a - b;
34       this.newCalc(`${a} - ${b}`, `${result}`);
35       return result
36     }
37
38     mul(a: number, b: number) {
39       let result = a * b;
40       this.newCalc(`${a} * ${b}`, `${result}`);
41       return result
42     }
43
44     div(a: number, b: number) {
45       let result = a / b;
46       this.newCalc(`${a} / ${b}`, `${result}`);
47       return result
48     }
49
50     getHistory(): collections.Array<collections.Array<string>> {
51       return this.history!;
52     }
53
54     showHistory() {
55       for (let i = 0; i < this.totalCount; i++) {
56         console.info(`${i}: ${this.history![i][0]} = ${this.history![i][1]}`)
57       }
58     }
59
60     private newCalc(opt: string, ret: string) {
61       let newRecord = new collections.Array<string>(opt, ret)
62       this.totalCount = this.history!.unshift(newRecord)
63     }
64   }
65   ```
66
67   The timer service module is defined as follows:
68
69   ```ts
70   // sdk/TimerSdk.ets
71   @Sendable
72   export class TimerSdk {
73     static init(): TimerSdk {
74       let timer = new TimerSdk()
75       return timer
76     }
77
78     async Countdown(time: number) {
79       return new Promise((resolve: (value: boolean) => void) => {
80         setTimeout(() => {
81           resolve(true)
82         }, time)
83       })
84     }
85   }
86   ```
87
882. The UI main thread triggers the distribution of each service module to the sub-thread. After the loading is complete, the UI main thread uses the service module.
89
90   ```ts
91   // Index.ets
92   import { Calculator } from '../sdk/Calculator'
93   import { TimerSdk } from '../sdk/TimerSdk'
94   import { taskpool } from '@kit.ArkTS';
95
96   @Concurrent
97   function initCalculator(): Calculator {
98     return Calculator.init()
99   }
100
101   @Concurrent
102   function initTimerSdk(): TimerSdk {
103     return TimerSdk.init()
104   }
105
106   @Entry
107   @Component
108   struct Index {
109     calc?: Calculator
110     timer?: TimerSdk
111
112     aboutToAppear(): void {
113       taskpool.execute(initCalculator).then((ret) => {
114         this.calc = ret as Calculator
115       })
116       taskpool.execute(initTimerSdk).then((ret) => {
117         this.timer = ret as TimerSdk
118       })
119     }
120
121     build() {
122       Row() {
123         Column() {
124           Text("calculate add")
125             .id('add')
126             .fontSize(50)
127             .fontWeight(FontWeight.Bold)
128             .alignRules({
129               center: { anchor: '__container__', align: VerticalAlign.Center },
130               middle: { anchor: '__container__', align: HorizontalAlign.Center }
131             })
132             .onClick(async () => {
133               let result = this.calc?.add(1, 2)
134               console.info(`Result is ${result}`)
135             })
136           Text("show history")
137             .id('show')
138             .fontSize(50)
139             .fontWeight(FontWeight.Bold)
140             .alignRules({
141               center: { anchor: '__container__', align: VerticalAlign.Center },
142               middle: { anchor: '__container__', align: HorizontalAlign.Center }
143             })
144             .onClick(async () => {
145               this.calc?.showHistory()
146             })
147           Text("countdown")
148             .id('get')
149             .fontSize(50)
150             .fontWeight(FontWeight.Bold)
151             .alignRules({
152               center: { anchor: '__container__', align: VerticalAlign.Center },
153               middle: { anchor: '__container__', align: HorizontalAlign.Center }
154             })
155             .onClick(async () => {
156               console.info(`Timer start`)
157               await this.timer?.Countdown(1000);
158               console.info(`Timer end`)
159             })
160         }
161         .width('100%')
162       }
163       .height('100%')
164     }
165   }
166   ```
167