【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. 参考文档

相关推荐
风满城3312 分钟前
【鸿蒙原生应用开发实战】第五篇:项目总结——ArkTS 最佳实践与从 MVP 到生产的升级之路
华为·harmonyos
木咺吟14 分钟前
鸿蒙原生应用实战(五):路由导航与工程优化 — 从开发到上线的完整流程
华为·harmonyos
风满城3318 分钟前
【鸿蒙原生应用开发实战】第三篇:表单录入与详情展示——AddPetPage + PetDetailPage 完整实现
华为·harmonyos
风满城331 小时前
【鸿蒙原生应用开发实战】第一篇:从零搭建“萌宠日记“项目——Stage模型与工程架构解析
华为·harmonyos
狼哥16861 小时前
《新闻资讯》二、公共能力层模块实现指南
ui·华为·harmonyos
Ww.xh2 小时前
启用Hypervisor解决模拟器问题
华为·harmonyos
金启攻2 小时前
【鸿蒙原生应用实战】第二篇:装备库页面——分类筛选与数据驱动UI
harmonyos
木咺吟4 小时前
鸿蒙原生应用实战(四):愿望单与个人统计 — 数据聚合与可视化
华为·harmonyos
木咺吟5 小时前
鸿蒙原生应用实战(二):游戏库列表与筛选排序 — 卡片式UI设计
harmonyos
互联网散修6 小时前
鸿蒙实战:从零实现自定义相机(下)——填平预览拉伸、比例错乱、缩略图消失的六大坑
数码相机·华为·harmonyos