【HarmonyOS Next】Promise你可能理解错了

【HarmonyOS Next】Promise你可能理解错了

记录一个很常见的认知误区,一段很简单的代码,在鸿蒙群里竟然都答错了。

用ArkTs开发鸿蒙产品,从前端转过来可能会更容易理解Promise、async、await。

1. 代码示例

下面是两段普通的ArkTs代码,如果你能很容易得出输出顺序,那么就可以跳过本篇文章了; 实际找了鸿蒙和前端群来说,答错的概率相当高。当然把ArkTs代码换成JS代码运行结果也是一样。

第一段代码,用setTimeout模拟延时,也是大部分博客模拟延时的方法。没理解为什么要用setTimeout模拟延时操作。

typescript 复制代码
async myFunction() {
    const result: string = await new Promise((resolve, reject) => {
      setTimeout(() => {
        console.info("C");
        resolve('Hello, world!');
      }, 1000);
    });
    return result;
  }

  // 入口
  async aboutToAppear() {
    console.info("A");
    this.myFunction();
    console.info("B");
  }

第一段代码输出ABC,相信很多人都没疑问。

第二段代码,用for循环代替setTimeout模拟延时。

typescript 复制代码
async myFunction() {
    const result: string = await new Promise((resolve, reject) => {
      for (let index = 0; index < 10000; index++) {

      }
      console.info("C");
      resolve('Hello, world!');
    });
    return result;
  }

  // 入口
  async aboutToAppear() {
    console.info("A");
    this.myFunction();
    console.info("B");
  }

结果输出ACB,无论this.myFunction()方法前是否加上await,结果都是ACB,有点懵了。

2. 解析

上诉两段代码,仅用for替代了setTimeout,为什么造成了结果不一致?

误区1:for与setTimeout都是模拟阻塞操作 误区2:Promise搭配async可以实现异步操作

(1) for循环是同步代码,setTimeout不是。

for循环在按顺序同步执行,没有什么好讲的;setTimeout是异步的宏任务。

JS中分为宏任务、微任务,宏任务包含setTimeout/setInterval等,微任务包含Promise.then。

执行顺序优先级是: 同步 > 微任务 > 宏任务

所以即使setTimeout的参数为0,它也不是立即执行,而是异步的宏任务。

(2) Promise只是解决异步回调的语法糖,方法体中不能异步,then是异步。

在Promise中写耗时操作会阻塞线程,如果想执行耗时操作,Promise解决不了问题,仍旧需要用线程(TaskPool和Worker)来实现异步操作。

所以Promise的诞生是为了更好的处理异步,让代码看起来简洁,在{}实现体中并不是真正可以异步,Promise.then是异步的微任务。

有一段前段代码证明Promise.then是异步的。

javascript 复制代码
 const main =async () => {
    return  new Promise ((resolve, reject)=>{
            console.log('d');
            if(true){
              resolve('1')
            }else{
              reject('1')
            }
            console.log('a');
      })
    }

const  init = async () =>{
  let res=  await main()
  if(res == '1'){
    console.log('c');
  }
  console.log('b');
}

输出dabc

3. 总结

Promise方法体中并不能带来异步能力,then方法体中是异步的微任务,且不能处理耗时任务。

总的来说Promise作用是能解决异步回调,使异步代码以同步的方式执行,不用太多callback。

鸿蒙文档描述:

Promise和async/await提供异步并发能力,是标准的JS异步语法。异步代码会被挂起并在之后继续执行,同一时间只有一段代码执行,适用于单次I/O任务的场景开发,例如一次网络请求、一次文件读写等操作。无需另外启动线程执行。

JS文档描述:

一个 Promise 是一个代理,它代表一个在创建 promise 时不一定已知的值。它允许你将处理程序与异步操作的最终成功值或失败原因关联起来。这使得异步方法可以像同步方法一样返回值:异步方法不会立即返回最终值,而是返回一个 promise,以便在将来的某个时间点提供该值。

这么看来JS文档中的描述更准确且更容易理解;并不是鸿蒙文档中的提供异步并发能力

对鸿蒙文档中的Promise和async/await提供异步并发能力表示质疑,欢迎留言讨论。

4. 参考文档

相关推荐
别说我什么都不会13 小时前
ohos.net.http请求HttpResponse header中set-ccokie值被转成array类型
网络协议·harmonyos
码是生活14 小时前
鸿蒙开发排坑:解决 resourceManager.getRawFileContent() 获取文件内容为空问题
前端·harmonyos
鸿蒙场景化示例代码技术工程师14 小时前
基于Canvas实现选座功能鸿蒙示例代码
华为·harmonyos
小脑斧爱吃鱼鱼15 小时前
鸿蒙项目笔记(1)
笔记·学习·harmonyos
鸿蒙布道师16 小时前
鸿蒙NEXT开发对象工具类(TS)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
zhang10620916 小时前
HarmonyOS 基础组件和基础布局的介绍
harmonyos·基础组件·基础布局
马剑威(威哥爱编程)16 小时前
在HarmonyOS NEXT 开发中,如何指定一个号码,拉起系统拨号页面
华为·harmonyos·arkts
GeniuswongAir17 小时前
Flutter极速接入IM聊天功能并支持鸿蒙
flutter·华为·harmonyos
90后的晨仔21 小时前
鸿蒙ArkUI框架中的状态管理
harmonyos
别说我什么都不会2 天前
OpenHarmony 5.0(API 12)关系型数据库relationalStore 新增本地数据变化监听接口介绍
api·harmonyos