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```