八、【鸿蒙 NEXT】ArkTS开发中遇到的注意点

前言:

在实际开发中,经常遇到一些细节的点,可能在出现问题时,看代码逻辑,没有任何问题,但是运行结果就是不符合预期,本节将梳理一些这样的问题点,希望能帮助到大家

一、number类型数据json解析后,被截断,导致逻辑错误

如果我们从后台接口返回的数据类型是一个long类型,比如一个id,而端侧定义的类型为number类型时,在进行json解析时,可能会出现精度丢失问题,如下通过JSON.parse解析时,实际解析获取的id=12345678901234567000,与实际不符,从而导致后续逻辑异常

let tmp = JSON.parse('{"name":"name","id":12345678901234567890}')

解决方案

1、如果后台接口返回的是string类型,端侧也用string类型接收

2、如果后台接口返回的本身就是long类型,可以使用三方库json-bigint做json解析,接收使用bigint类型接收,代码示例如下

OpenHarmony三方库中心仓https://ohpm.openharmony.cn/#/cn/detail/@ohmos%2Fjson-bigint

let tmp1 = JsonBigInt.parse('{"name":"name","id":12345678901234567890}') as Person;
console.log(`${tmp1.id}`)

class Person {
  name:string = ''
  id:bigint =BigInt(0)
}

二、map的json序列化是空字符串(包括set)

JSON.stringify()是js语法,在ArkTS中仅支持特定类型的json转换。我们可以通过如下方法解决

1、将Map转为Record,然后对Record对象进行JSON.stringify转换获取json字符串

mapToRecord(map: Map<string, Object>): Record<string, Object> {
    let ret: Record<string, Object> = {}
    map.forEach((val, key) => {
      ret[key] = val
    })
    return ret;
  }

2、直接用Record对象替换map来使用

 let ret: Record<string, Object> = {"name":"name","id": 1}
 console.log(JSON.stringify(ret))

三、如何遍历Enum枚举值

我们可能和后台交互时,会根据接口返回的枚举key,查询对应的value值等等场景,会需要遍历枚举的场景,可以参考如下:

enum MyEnum {
  'A' = 'a',
  'B' = 'b'
}

function test() {
  let enumKeys = Object.keys(MyEnum).filter(key => isNaN(Number(key)));
  let enumVals = enumKeys.map(key => MyEnum[key as keyof object])
  console.log("keys:", enumKeys) // keys: A,B
  console.log("vals:", enumVals) // vals: a,b
}

四、try catch中e对象的类型,如何打印异常信息,有时候直接打印json序列化为空,可以参考如下打印,如果要打印堆栈信息可以转为BusinessError对象

async print() {
    try {
      let a = await this.test({"name":new Person()})
      return a
    } catch (e) {
      console.log(`error: ${e}`)
      console.log(`error json: ${JSON.stringify(e)}`)
      console.log(`error code: ${(e as BusinessError).code}`)
      console.log(`error message: ${(e as BusinessError).message}`)
      console.log(`error stack: ${(e as BusinessError).stack}`)
    }
    return 1
  }

如上构造了一个空指针异常,打印异常如下:

五、setTimeout,setInterval启动后定时任务没生效

解决方法:setTimeout,setInterval的默认id不要设置为0,需要设置为-1

在开发过程中,有时候我们会发现,我们设置的setTimeout或者setInterval定时任务没有生效,但是明明代码里已经启动了定时任务。这里有个注意点,就是定时任务的id都是从0开始的,如果我们app有如下的逻辑,在启动一个定时任务时,会先清除下上次启动的任务,如果这里保存的全局id默认是0的话,可能会误把其他地方启动的定时任务给清除掉,导致任务没执行。所以我们的默认id初始值需要赋值为-1。另外还有一点就是clearTimeout和clearInterval会互相清除,这也是一个注意点,不知道后续鸿蒙的系统版本会不会修复这个问题。

  id1 = 0
  id2 = 0

  test1() {
    clearTimeout(this.id1)
    let id1 = setTimeout(() => {
      console.log('')
    })
    clearInterval(this.id2)
    let id2 = setInterval(() => {
      console.log('')
    }, 1000)
  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值