HarmonyOS 鸿蒙Next 关于Promise的用法和隐患 咨询

发布于 1周前 作者 caililin 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 关于Promise的用法和隐患 咨询

由于我们app使用了大量promise,因此我们做了以下实验,产生了几个问题:

我们的测试代码如下:

private testPromise(){
  for (let i = 0; i < 10; i++) {
    this.testPromiseImp(i).then(()=>{})
  }

  let promise1 = this.testPromiseImp(101)
  let promise2 = this.testPromiseImp(102)
  let promise3 = this.testPromiseImp(103)
  let promise4 = this.testPromiseImp(104)
  let promise5 = this.testPromiseImp(105)
  Promise.all([promise1,promise2,promise3,promise4,promise5]).then(()=>{
    LogUtils.info(TAG,"并发完成")
  })
}

private testPromiseImp(index:number):Promise<void>{
  return new Promise((resolve,reject)=>{
    let time = Date.now()
    LogUtils.info(TAG,"testPromiseImp index start :"+index+" isMainThread:"+TaskManager.getInstance().isMainThread())
    for (let i = 0; i < 1000; i++) {
    try {
      let path = MYFileManager.getInstance().getAppCacheDir()+"/test.txt"
      MYFileManager.getInstance().saveStringToFileSync(path,"我是测试字符串:"+index)
    } catch (e) {
      LogUtils.error(TAG,"写入异常:"+e)
    }
    }
    let timeEnd = Date.now()
    LogUtils.info(TAG,"===>testPromiseImp index end :"+index+" 耗时:"+(timeEnd-time))
    resolve()
  })
}

测试结果日志如下:

05-07 10:23:53.064 testPromiseImp index start :0 isMainThread:true
05-07 10:23:53.104 ===>testPromiseImp index end :0 耗时:40
05-07 10:23:53.104 testPromiseImp index start :1 isMainThread:true
05-07 10:23:53.139 ===>testPromiseImp index end :1 耗时:35
05-07 10:23:53.139 testPromiseImp index start :2 isMainThread:true
05-07 10:23:53.173 ===>testPromiseImp index end :2 耗时:34
05-07 10:23:53.173 testPromiseImp index start :3 isMainThread:true
05-07 10:23:53.206 ===>testPromiseImp index end :3 耗时:33
05-07 10:23:53.206 testPromiseImp index start :4 isMainThread:true
05-07 10:23:53.241 ===>testPromiseImp index end :4 耗时:35
05-07 10:23:53.241 testPromiseImp index start :5 isMainThread:true
05-07 10:23:53.275 ===>testPromiseImp index end :5 耗时:34
05-07 10:23:53.275 testPromiseImp index start :6 isMainThread:true
05-07 10:23:53.309 ===>testPromiseImp index end :6 耗时:34
05-07 10:23:53.309 testPromiseImp index start :7 isMainThread:true
05-07 10:23:53.343 ===>testPromiseImp index end :7 耗时:34
05-07 10:23:53.343 testPromiseImp index start :8 isMainThread:true
05-07 10:23:53.377 ===>testPromiseImp index end :8 耗时:34
05-07 10:23:53.377 testPromiseImp index start :9 isMainThread:true
05-07 10:23:53.412 ===>testPromiseImp index end :9 耗时:35
05-07 10:23:53.412 testPromiseImp index start :101 isMainThread:true
05-07 10:23:53.446 ===>testPromiseImp index end :101 耗时:34
05-07 10:23:53.446 testPromiseImp index start :102 isMainThread:true
05-07 10:23:53.481 ===>testPromiseImp index end :102 耗时:35
05-07 10:23:53.481 testPromiseImp index start :103 isMainThread:true
05-07 10:23:53.514 ===>testPromiseImp index end :103 耗时:33
05-07 10:23:53.514 testPromiseImp index start :104 isMainThread:true
05-07 10:23:53.548 ===>testPromiseImp index end :104 耗时:34
05-07 10:23:53.548 testPromiseImp index start :105 isMainThread:true
05-07 10:23:53.583 ===>testPromiseImp index end :105 耗时:35
05-07 10:23:53.583 并发完成

通过以上测试我们认为:

  1. Promise同一时间只能执行一个,这个和官方说法一致;但使用Promise.all依然也是按顺序执行,不是并发执行。

  2. Promise是按顺序执行的,也就是说,比如app 从启动->欢迎页->首页,首页启动的promse必须等前边的promise执行完成后,才会进行。那如果前边的promise有任意一个卡住了,比如http卡住超时了,那整个promise链路都会进行等待,这种体验风险是不是极大?请问要如何解决;(由于taskpool和worker的内存独立不共享问题,导致很多业务很难使用这种线程池的方案)

  3. Promise运行的线程是在主线程,那当进行文件操作的时候,是否会出现类似android的anr,我发现我进行await 100次后,会出现appfreeze这种类型的闪退,那是不是意味着,其他的promise类型也会造成闪退?


更多关于HarmonyOS 鸿蒙Next 关于Promise的用法和隐患 咨询的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复
  1. Promise的本质其实就是微服务队列
  2. 是的,Promise中不建议执行耗时的任务,耗时的任务建议使用taskpool或者worker
  3. 主线程中执行的Promise,执行耗时的任务,会存在ANR,只有在taskpool或者worker中执行的Promise不会ANR

更多关于Promise的使用,可见:[HarmonyOS NEXT] 异步编程的神器之Promise
https://juejin.cn/post/7438295037275488296

更多关于HarmonyOS 鸿蒙Next 关于Promise的用法和隐患 咨询的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS(鸿蒙)Next中,Promise是一种用于异步编程的机制,它允许你编写更简洁、更易于理解的异步代码。以下是对Promise在鸿蒙中的用法及隐患的简要说明:

用法:

  1. 创建Promise:使用new Promise((resolve, reject) => { ... })来创建一个Promise对象,其中resolvereject是两个函数,分别用于在异步操作成功或失败时调用。

  2. 使用Promise:通过.then(onFulfilled, onRejected)方法添加成功和失败的回调函数。也可以使用.catch(onRejected)方法专门捕获失败的情况。

  3. 链式调用:Promise支持链式调用,即一个Promise的结果可以作为下一个Promise的输入。

隐患:

  1. 错误处理:如果忘记添加.catch方法或在链式调用中未正确处理错误,可能会导致未捕获的异常。

  2. 性能问题:过多的Promise嵌套或链式调用可能会导致性能下降,尤其是在处理大量异步操作时。

  3. 调试困难:Promise的异步特性使得调试变得复杂,特别是当涉及到多个Promise的并行或串行执行时。

如果问题依旧没法解决请联系官网客服,官网地址是: https://www.itying.com/category-93-b0.html

回到顶部