1e41f4b71Sopenharmony_ci# Sendable使用场景 2e41f4b71Sopenharmony_ciSendable对象可以在不同并发实例间通过引用传递。通过引用传递方式传输对象相比序列化方式更加高效,同时不会丢失class上携带的成员方法。因此,Sendable主要可以解决两个场景的问题: 3e41f4b71Sopenharmony_ci 4e41f4b71Sopenharmony_ci- 跨并发实例传输大数据(例如可能达到100KB以上的数据)。 5e41f4b71Sopenharmony_ci 6e41f4b71Sopenharmony_ci- 跨并发实例传递带方法的class实例对象。 7e41f4b71Sopenharmony_ci 8e41f4b71Sopenharmony_ci## 跨并发实例传输大数据场景 9e41f4b71Sopenharmony_ci 10e41f4b71Sopenharmony_ci由于跨并发实例序列化的开销随着数据量线性增长,因此当传输数据量较大时(100KB数据大约1ms传输耗时),跨并发实例的拷贝开销大,影响应用性能。引用传递方式传输对象可提升性能。 11e41f4b71Sopenharmony_ci 12e41f4b71Sopenharmony_ci**示例:** 13e41f4b71Sopenharmony_ci 14e41f4b71Sopenharmony_ci```ts 15e41f4b71Sopenharmony_ci// Index.ets 16e41f4b71Sopenharmony_ciimport { taskpool } from '@kit.ArkTS'; 17e41f4b71Sopenharmony_ciimport { testTypeA, testTypeB, Test } from './sendable' 18e41f4b71Sopenharmony_ciimport { BusinessError, emitter } from '@kit.BasicServicesKit'; 19e41f4b71Sopenharmony_ci 20e41f4b71Sopenharmony_ci// 在并发函数中模拟数据处理 21e41f4b71Sopenharmony_ci@Concurrent 22e41f4b71Sopenharmony_ciasync function taskFunc(obj: Test) { 23e41f4b71Sopenharmony_ci console.info("test task res1 is: " + obj.data1.name + " res2 is: " + obj.data2.name); 24e41f4b71Sopenharmony_ci} 25e41f4b71Sopenharmony_ci 26e41f4b71Sopenharmony_ciasync function test() { 27e41f4b71Sopenharmony_ci // 使用taskpool传递数据 28e41f4b71Sopenharmony_ci let a: testTypeA = new testTypeA("testTypeA"); 29e41f4b71Sopenharmony_ci let b: testTypeB = new testTypeB("testTypeB"); 30e41f4b71Sopenharmony_ci let obj: Test = new Test(a, b); 31e41f4b71Sopenharmony_ci let task: taskpool.Task = new taskpool.Task(taskFunc, obj); 32e41f4b71Sopenharmony_ci await taskpool.execute(task); 33e41f4b71Sopenharmony_ci} 34e41f4b71Sopenharmony_ci 35e41f4b71Sopenharmony_ci@Concurrent 36e41f4b71Sopenharmony_cifunction SensorListener() { 37e41f4b71Sopenharmony_ci // 监听逻辑 38e41f4b71Sopenharmony_ci // ... 39e41f4b71Sopenharmony_ci} 40e41f4b71Sopenharmony_ci 41e41f4b71Sopenharmony_ci@Entry 42e41f4b71Sopenharmony_ci@Component 43e41f4b71Sopenharmony_cistruct Index { 44e41f4b71Sopenharmony_ci build() { 45e41f4b71Sopenharmony_ci Column() { 46e41f4b71Sopenharmony_ci Text("Listener task") 47e41f4b71Sopenharmony_ci .id('HelloWorld') 48e41f4b71Sopenharmony_ci .fontSize(50) 49e41f4b71Sopenharmony_ci .fontWeight(FontWeight.Bold) 50e41f4b71Sopenharmony_ci .onClick(() => { 51e41f4b71Sopenharmony_ci let sensorTask = new taskpool.LongTask(SensorListener); 52e41f4b71Sopenharmony_ci emitter.on({ eventId: 0 }, (data) => { 53e41f4b71Sopenharmony_ci // Do something here 54e41f4b71Sopenharmony_ci console.info(`Receive ACCELEROMETER data: {${data.data?.x}, ${data.data?.y}, ${data.data?.z}`); 55e41f4b71Sopenharmony_ci }); 56e41f4b71Sopenharmony_ci taskpool.execute(sensorTask).then(() => { 57e41f4b71Sopenharmony_ci console.info("Add listener of ACCELEROMETER success"); 58e41f4b71Sopenharmony_ci }).catch((e: BusinessError) => { 59e41f4b71Sopenharmony_ci // Process error 60e41f4b71Sopenharmony_ci }) 61e41f4b71Sopenharmony_ci }) 62e41f4b71Sopenharmony_ci Text("Data processing task") 63e41f4b71Sopenharmony_ci .id('HelloWorld') 64e41f4b71Sopenharmony_ci .fontSize(50) 65e41f4b71Sopenharmony_ci .fontWeight(FontWeight.Bold) 66e41f4b71Sopenharmony_ci .onClick(() => { 67e41f4b71Sopenharmony_ci test(); 68e41f4b71Sopenharmony_ci }) 69e41f4b71Sopenharmony_ci } 70e41f4b71Sopenharmony_ci .height('100%') 71e41f4b71Sopenharmony_ci .width('100%') 72e41f4b71Sopenharmony_ci } 73e41f4b71Sopenharmony_ci} 74e41f4b71Sopenharmony_ci``` 75e41f4b71Sopenharmony_ci 76e41f4b71Sopenharmony_ci```ts 77e41f4b71Sopenharmony_ci// sendable.ets 78e41f4b71Sopenharmony_ci// 将数据量较大的数据在Sendable class中组装 79e41f4b71Sopenharmony_ci@Sendable 80e41f4b71Sopenharmony_ciexport class testTypeA { 81e41f4b71Sopenharmony_ci name: string = "A"; 82e41f4b71Sopenharmony_ci constructor(name: string) { 83e41f4b71Sopenharmony_ci this.name = name; 84e41f4b71Sopenharmony_ci } 85e41f4b71Sopenharmony_ci} 86e41f4b71Sopenharmony_ci 87e41f4b71Sopenharmony_ci@Sendable 88e41f4b71Sopenharmony_ciexport class testTypeB { 89e41f4b71Sopenharmony_ci name: string = "B"; 90e41f4b71Sopenharmony_ci constructor(name: string) { 91e41f4b71Sopenharmony_ci this.name = name; 92e41f4b71Sopenharmony_ci } 93e41f4b71Sopenharmony_ci} 94e41f4b71Sopenharmony_ci 95e41f4b71Sopenharmony_ci@Sendable 96e41f4b71Sopenharmony_ciexport class Test { 97e41f4b71Sopenharmony_ci data1: testTypeA; 98e41f4b71Sopenharmony_ci data2: testTypeB; 99e41f4b71Sopenharmony_ci constructor(arg1: testTypeA, arg2: testTypeB) { 100e41f4b71Sopenharmony_ci this.data1 = arg1; 101e41f4b71Sopenharmony_ci this.data2 = arg2; 102e41f4b71Sopenharmony_ci } 103e41f4b71Sopenharmony_ci} 104e41f4b71Sopenharmony_ci``` 105e41f4b71Sopenharmony_ci 106e41f4b71Sopenharmony_ci 107e41f4b71Sopenharmony_ci## 跨并发实例传递带方法的class实例对象 108e41f4b71Sopenharmony_ci 109e41f4b71Sopenharmony_ci由于序列化传输实例对象时会丢失方法,在必须调用实例方法的场景中,需使用引用传递方式进行开发。在数据处理过程中有需要解析的数据,可使用[ASON工具](ason-parsing-generation.md)进行数据解析。 110e41f4b71Sopenharmony_ci 111e41f4b71Sopenharmony_ci 112e41f4b71Sopenharmony_ci**示例:** 113e41f4b71Sopenharmony_ci 114e41f4b71Sopenharmony_ci```ts 115e41f4b71Sopenharmony_ci// Index.ets 116e41f4b71Sopenharmony_ciimport { taskpool, ArkTSUtils } from '@kit.ArkTS' 117e41f4b71Sopenharmony_ciimport { SendableTestClass, ISendable } from './sendable' 118e41f4b71Sopenharmony_ci 119e41f4b71Sopenharmony_ci// 在并发函数中模拟数据处理 120e41f4b71Sopenharmony_ci@Concurrent 121e41f4b71Sopenharmony_ciasync function taskFunc(sendableObj: SendableTestClass) { 122e41f4b71Sopenharmony_ci console.info("SendableTestClass: name is: " + sendableObj.printName() + ", age is: " + sendableObj.printAge() + ", sex is: " + sendableObj.printSex()); 123e41f4b71Sopenharmony_ci sendableObj.setAge(28); 124e41f4b71Sopenharmony_ci console.info("SendableTestClass: age is: " + sendableObj.printAge()); 125e41f4b71Sopenharmony_ci 126e41f4b71Sopenharmony_ci // 解析sendableObj.arr数据生成JSON字符串 127e41f4b71Sopenharmony_ci let str = ArkTSUtils.ASON.stringify(sendableObj.arr); 128e41f4b71Sopenharmony_ci console.info("SendableTestClass: str is: " + str); 129e41f4b71Sopenharmony_ci 130e41f4b71Sopenharmony_ci // 解析该数据并生成ISendable数据 131e41f4b71Sopenharmony_ci let jsonStr = '{"name": "Alexa", "age": 23, "sex": "female"}'; 132e41f4b71Sopenharmony_ci let obj = ArkTSUtils.ASON.parse(jsonStr) as ISendable; 133e41f4b71Sopenharmony_ci console.info("SendableTestClass: type is: " + typeof obj); 134e41f4b71Sopenharmony_ci console.info("SendableTestClass: name is: " + (obj as object)?.["name"]); // 输出: 'Alexa' 135e41f4b71Sopenharmony_ci console.info("SendableTestClass: age is: " + (obj as object)?.["age"]); // 输出: 23 136e41f4b71Sopenharmony_ci console.info("SendableTestClass: sex is: " + (obj as object)?.["sex"]); // 输出: 'female' 137e41f4b71Sopenharmony_ci} 138e41f4b71Sopenharmony_ciasync function test() { 139e41f4b71Sopenharmony_ci // 使用taskpool传递数据 140e41f4b71Sopenharmony_ci let obj: SendableTestClass = new SendableTestClass(); 141e41f4b71Sopenharmony_ci let task: taskpool.Task = new taskpool.Task(taskFunc, obj); 142e41f4b71Sopenharmony_ci await taskpool.execute(task); 143e41f4b71Sopenharmony_ci} 144e41f4b71Sopenharmony_ci 145e41f4b71Sopenharmony_ci@Entry 146e41f4b71Sopenharmony_ci@Component 147e41f4b71Sopenharmony_cistruct Index { 148e41f4b71Sopenharmony_ci @State message: string = 'Hello World'; 149e41f4b71Sopenharmony_ci 150e41f4b71Sopenharmony_ci build() { 151e41f4b71Sopenharmony_ci RelativeContainer() { 152e41f4b71Sopenharmony_ci Text(this.message) 153e41f4b71Sopenharmony_ci .id('HelloWorld') 154e41f4b71Sopenharmony_ci .fontSize(50) 155e41f4b71Sopenharmony_ci .fontWeight(FontWeight.Bold) 156e41f4b71Sopenharmony_ci .alignRules({ 157e41f4b71Sopenharmony_ci center: { anchor: '__container__', align: VerticalAlign.Center }, 158e41f4b71Sopenharmony_ci middle: { anchor: '__container__', align: HorizontalAlign.Center } 159e41f4b71Sopenharmony_ci }) 160e41f4b71Sopenharmony_ci .onClick(() => { 161e41f4b71Sopenharmony_ci test(); 162e41f4b71Sopenharmony_ci }) 163e41f4b71Sopenharmony_ci } 164e41f4b71Sopenharmony_ci .height('100%') 165e41f4b71Sopenharmony_ci .width('100%') 166e41f4b71Sopenharmony_ci } 167e41f4b71Sopenharmony_ci} 168e41f4b71Sopenharmony_ci``` 169e41f4b71Sopenharmony_ci 170e41f4b71Sopenharmony_ci```ts 171e41f4b71Sopenharmony_ci// sendable.ets 172e41f4b71Sopenharmony_ci// 定义模拟类Test,模仿开发过程中需传递带方法的class 173e41f4b71Sopenharmony_ciimport { lang, collections } from '@kit.ArkTS' 174e41f4b71Sopenharmony_ci 175e41f4b71Sopenharmony_ciexport type ISendable = lang.ISendable; 176e41f4b71Sopenharmony_ci 177e41f4b71Sopenharmony_ci@Sendable 178e41f4b71Sopenharmony_ciexport class SendableTestClass { 179e41f4b71Sopenharmony_ci name: string = 'John'; 180e41f4b71Sopenharmony_ci age: number = 20; 181e41f4b71Sopenharmony_ci sex: string = "man"; 182e41f4b71Sopenharmony_ci arr: collections.Array<number> = new collections.Array<number>(1, 2, 3); 183e41f4b71Sopenharmony_ci constructor() { 184e41f4b71Sopenharmony_ci } 185e41f4b71Sopenharmony_ci setAge(age: number) : void { 186e41f4b71Sopenharmony_ci this.age = age; 187e41f4b71Sopenharmony_ci } 188e41f4b71Sopenharmony_ci 189e41f4b71Sopenharmony_ci printName(): string { 190e41f4b71Sopenharmony_ci return this.name; 191e41f4b71Sopenharmony_ci } 192e41f4b71Sopenharmony_ci 193e41f4b71Sopenharmony_ci printAge(): number { 194e41f4b71Sopenharmony_ci return this.age; 195e41f4b71Sopenharmony_ci } 196e41f4b71Sopenharmony_ci 197e41f4b71Sopenharmony_ci printSex(): string { 198e41f4b71Sopenharmony_ci return this.sex; 199e41f4b71Sopenharmony_ci } 200e41f4b71Sopenharmony_ci} 201e41f4b71Sopenharmony_ci```