1# 共享模块 2 3共享模块是进程内只会加载一次的模块,使用"use shared"这一指令来标记一个模块是否为共享模块。 4 5非共享模块在同一线程内只加载一次,在不同线程间会加载多次,在不同的线程内都会产生新的模块对象。因此可以使用共享模块来实现进程单例。 6 7 8## 约束限制 9 10- "use shared"需要与"use strict"一样写在ArkTS文件顶层,写在import语句之后其他语句之前。 11 12 共享属性不存在传递性,即非共享模块A不会引入了共享模块B而使A变成共享。 13 14 15- 共享模块只支持ets文件。 16 17- 共享模块内不允许使用side-effects-import。 18 19 共享模块可在线程间共享,共享后函数对依赖的非共享模块会在获取模块化变量值的时候懒加载,这种类型的import不涉及导出变量,所以不会被加载。 20 21 ```ts 22 // 不允许使用side-effects-import 23 import "./sharedModule" 24 ``` 25 26- 共享模块导出的变量必须都是可共享对象。 27 28 共享模块在并发实例间可共享,因此模块导出的所有对象都必须是可共享的,可共享对象参考[Sendable规格](sendable-constraints.md)。 29 30- 共享模块中不允许直接导出模块。 31 32 ```ts 33 // test.ets 34 export let num = 1; 35 export let str = 'aaa'; 36 37 // 共享模块 38 'use shared' 39 40 export * from './test'; // 编译报错,不允许直接导出模块 41 export {num, str} from './test'; // 正确示例,导出对象合集 42 ``` 43 44 45- 共享模块可以引用共享模块或非共享模块。不限制共享模块的引用和被引用场景。 46 47- napi_load_module、napi_load_module_with_info以及动态加载不支持加载共享模块。 48 49 50## 使用示例 51 521. 共享模块内导出Sendable对象。 53 54 ```ts 55 // 共享模块sharedModule.ets 56 import { ArkTSUtils } from '@kit.ArkTS'; 57 58 // 声明当前模块为共享模块,只能导出可Sendable数据 59 "use shared" 60 61 // 共享模块,SingletonA全局唯一 62 @Sendable 63 class SingletonA { 64 private count_: number = 0; 65 lock_: ArkTSUtils.locks.AsyncLock = new ArkTSUtils.locks.AsyncLock() 66 67 public async getCount(): Promise<number> { 68 return this.lock_.lockAsync(() => { 69 return this.count_; 70 }) 71 } 72 73 public async increaseCount() { 74 await this.lock_.lockAsync(() => { 75 this.count_++; 76 }) 77 } 78 } 79 80 export let singletonA = new SingletonA(); 81 ``` 82 832. 在多个线程中操作共享模块导出的对象。 84 85 ```ts 86 import { ArkTSUtils, taskpool } from '@kit.ArkTS'; 87 import { singletonA } from './sharedModule'; 88 89 @Sendable 90 export class A { 91 private count_: number = 0; 92 lock_: ArkTSUtils.locks.AsyncLock = new ArkTSUtils.locks.AsyncLock(); 93 94 public async getCount(): Promise<number> { 95 return this.lock_.lockAsync(() => { 96 return this.count_; 97 }) 98 } 99 100 public async increaseCount() { 101 await this.lock_.lockAsync(() => { 102 this.count_++; 103 }) 104 } 105 } 106 107 @Concurrent 108 async function increaseCount() { 109 await singletonA.increaseCount(); 110 console.info("SharedModule: count is:" + await singletonA.getCount()); 111 } 112 113 @Concurrent 114 async function printCount() { 115 console.info("SharedModule: count is:" + await singletonA.getCount()); 116 } 117 118 @Entry 119 @Component 120 struct Index { 121 @State message: string = 'Hello World'; 122 123 build() { 124 Row() { 125 Column() { 126 Button("MainThread print count") 127 .onClick(async () => { 128 await printCount(); 129 }) 130 Button("Taskpool print count") 131 .onClick(async () => { 132 await taskpool.execute(printCount); 133 }) 134 Button("MainThread increase count") 135 .onClick(async () => { 136 await increaseCount(); 137 }) 138 Button("Taskpool increase count") 139 .onClick(async () => { 140 await taskpool.execute(increaseCount); 141 }) 142 } 143 .width('100%') 144 } 145 .height('100%') 146 } 147 } 148 ``` 149