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