• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# ArkTS运行时常见问题
2<!--Kit: ArkTS-->
3<!--Subsystem: ArkCompiler-->
4<!--Owner: @DaiHuina1997-->
5<!--Designer: @yao_dashuai-->
6<!--Tester: @kirl75; @zsw_zhushiwei-->
7<!--Adviser: @foryourself-->
8
9## 方舟正则运算与预期输出结果不一致场景
10
11如果使用方舟正则运算时结果与期望不符,请检查以下场景。
12
13### 方舟正则运算对于\b处理与预期不一致
14
15   ```ts
16   let str = "\u2642";
17   let res = str.replace(/\b/g, "/");
18   console.info("res = " + res);
19   // 期望输出: res = ♂
20   // 实际输出: res = /♂/
21   ```
22
23   规避方案:暂无。
24   > **说明:**
25   >
26   > 正则匹配\b(单词边界)遇到某些ASCII编码之外的字符时,会将其当成ASCII字符来处理,从而将不是单词边界匹配识别成单词边界。
27
28### 方舟正则运算对于先行断言((?=pattern)或(?!pattern)) 嵌套在后行断言((?<=pattern)或(?<!pattern))内部的场景与预期不一致
29
30   ```ts
31   console.info(`res:${"abcdef".match(/(?<=ab(?=c)cd)ef/)}`);
32   // 期望输出: res:ef
33   // 实际输出: res:null
34   ```
35
36   规避方案:使用/(?<=abcd)ef/代替/(?<=ab(?=c)cd)ef/。
37
38### 方舟正则运算对于大小写的处理与预期不一致
39
40   ```ts
41   let res = /\u{10400}/ui.test("\u{10428}");
42   console.info("res = " + res);
43   // 期望输出: res = true
44   // 实际输出: res = false
45   ```
46
47   规避方案:暂无。
48
49### 方舟正则运算/()/ug匹配时lastIndex与预期不一致
50
51   ```ts
52   let L = "\ud800";
53   let T = "\udc00";
54   let u = /()/ug;
55   u.lastIndex = 1;
56   u.exec(L + T + L + T);
57   console.info("u.lastIndex = " + u.lastIndex);
58   // 期望输出: u.lastIndex = 0
59   // 实际输出: u.lastIndex = 1
60   ```
61
62   规避方案:暂无。
63
64### 方舟正则运算[]内部使用'-'与预期不一致
65
66   ```ts
67   let str =  "a-b";
68   let reg = /[+-\s]/;
69   console.info("reg.exec(str) = " + reg.exec(str));
70   // 期望输出: reg.exec(str) = -
71   // 实际输出: reg.exec(str) = null
72   ```
73
74   规避方案:使用转义后的"-"。
75   ```ts
76   let str =  "a-b";
77   let reg = /[+\-\s]/;
78   console.info("reg.exec(str) = " + reg.exec(str));
79   ```
80
81### 方舟正则运算具名捕获组获取与预期不一致
82
83   ```ts
84   let reg = new RegExp("(a)(?<b>b)");
85   let res = reg.exec("ab");
86   console.info("JSON.stringify(res?.groups) = " + JSON.stringify(res?.groups));
87   // 期望输出: JSON.stringify(res?.groups) = {"b":"b"}
88   // 实际输出: JSON.stringify(res?.groups) = {"b":"a"}
89   ```
90
91   规避方案:计算具名捕获组位置获取具名捕获组匹配的内容。
92
93   ```ts
94   let reg = new RegExp("(a)(?<b>b)");
95   let res = reg.exec("ab") as Array<string>;
96   console.info(JSON.stringify(res[2]));
97   ```
98
99### 方舟正则匹配使用'|'与预期不一致
100
101   在使用正则匹配时,如果'|'前是一个空匹配,会导致'|'后的匹配不成功。
102
103   ```ts
104   let reg = /a(?:|x)$/;
105   let res = reg.exec("ax");
106   console.info("JSON.stringify(res) = " + JSON.stringify(res));
107   // 期望输出: JSON.stringify(res) = ["ax"]
108   // 实际输出: JSON.stringify(res) = null
109   ```
110
111   规避方案:使用reg2或reg3替换reg1。
112
113   ```ts
114   let reg1 = /a(?:|x)$/;
115   let reg2 = /a(?:x)?$/;
116   let reg3 = /a(?:x){0,1}$/;
117   ```
118
119### 方舟字符串 `replace` 接口对于第一个参数为空字符串的场景与预期不一致
120
121   在使用字符串replace接口时,如果第一个参数是空字符串,则直接返回原始字符串。
122
123   ```ts
124   let str = "dddd"
125   let res = str.replace("", "abc");
126   console.info("res = " + res);
127   // 期望输出: res = abcdddd
128   // 实际输出: res = dddd
129   ```
130
131   规避方案:使用正则表达式 `/^/` 表示字符串起始符,作为第一个参数。
132
133   ```ts
134   let str = "dddd"
135   let res = str.replace(/^/, "abc");
136   ```
137
138## Async函数内部异常的处理机制
139
140**场景**
141
142如果在Async函数内部产生了异常,且没有使用catch捕获该异常,在ArkTS中不会导致进程退出。其本质是Async函数返回了一个rejected状态的Promise对象,没有被处理,使得Promise的rejected状态没有被捕获。Async函数内部的异常会变成 unhandledRejection,表现为异常未抛出。
143
144**Async函数内部异常的捕获方式**
145
1461. 使用[errorManager.on()](../reference/apis-ability-kit/js-apis-app-ability-errorManager.md#errormanageronerror)捕获到Async函数产生的unhandledrejection事件,再通过编写errorManager.on()注册的回调函数,来进行异常处理操作。
147
148   ```ts
149      errorManager.on("unhandledRejection", (a:ESObject, b:Promise<ESObject>) => {
150         console.info("Async test", a);
151      })
152   ```
153
1542. 在Async函数内部,针对可能发生异常的代码块添加try-catch逻辑,直接捕获可能出现的异常。
155
156> **注意:**
157>
158> 注意必须在Async函数内部,外部无法捕获Async函数内部的异常,外部只能通过errorManager.on()监听。
159
160
161**查看Async函数内部是否有异常的方式**
162
163若开发者仅需要查看Async函数内部是否产生异常,首先需要在DevEco Studio终端执行以下hilog命令开启debug级别日志打印:
164
165```shell
166   hilog -b D
167```
168
169然后点击DevEco Studio下方HiLog选项卡,输入过滤条件“Throw error:”,即可查看到Async函数内产生的异常信息。
170![alt text](figures/arkts-runtime-faq.png)
171
172## 方舟Array.flatMap()接口常见问题
173
174Array.flatMap()接口在处理包含Proxy的Array时,未正确展平嵌套的Proxy Array,导致返回结果与预期不一致。
175
176### ArkTS使用场景
177
178```ts
179let arr1 = [0, 1];
180let arr2 = [2, 3];
181const emptyHandler = new Object() as ProxyHandler<number[]>;
182let proxy1 = new Proxy(arr1, emptyHandler);
183let proxy2 = new Proxy(arr2, emptyHandler);
184let arr3 = [proxy1, proxy2];
185let res = arr3.flatMap(x => x);
186
187console.log("res length:", res.length.toString());
188// 期望输出: res length: 4
189// 实际输出: res length: 2
190console.log("res[0] is: ", res[0].toString());
191// 期望输出: res[0] is: 0
192// 实际输出: res[0] is: 0,1
193```
194
195### ArkUI使用场景
196
197ArkUI状态管理框架会为使用状态变量装饰器(如@State、@Trace、@Local)装饰的Array添加一层代理,用于观测API调用产生的变化。如果状态修饰器与Array组合,并且调用Array.flatMap,会出现如下问题。
198
199以状态管理V2为例:
200
201```ts
202@Entry
203@ComponentV2
204struct Index {
205   @Local p: number[] = [0, 1];
206   @Local q: number[] = [2, 3];
207   c: number[][] = [this.p, this.q];
208   d: number[] = [];
209
210   aboutToAppear(): void {
211      this.d = this.c.flatMap(it => it);
212   }
213
214   build() {
215      Column() {
216         Text(`${this.d[0]}`); // 预期显示:0; 实际显示:0,1
217      }
218   }
219}
220```
221
222### Array.flatMap规避方案
223
224避免使用Array.flatMap()接口,改为调用Array.map()接口后再调用深度为1的Array.flat()接口。以上文ArkTS使用场景为例:
225
226```ts
227// 使用规避方案前
228let res = arr3.flatMap(x => x);
229// 使用规避方案后
230let res = arr3.map(x => x).flat();
231```