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

相关推荐
TrisighT16 小时前
DevEco Code 写鸿蒙 ArkTS 确实快,但我试了三天后把默认引擎换成了 Cursor
ai编程·harmonyos·cursor
liz7up16 小时前
鸿蒙原生流程图 & 审批流组件 hmflowkit
harmonyos
网易云信1 天前
全框架覆盖!网易智企IM鸿蒙生态适配再进一步
人工智能·aigc·harmonyos
TrisighT2 天前
我用 AI 逆向了 ArkTS @Builder 的编译产物,看完再也不敢乱写嵌套了
ai编程·harmonyos·arkts
ONEDAY3 天前
HarmonyOS 深色模式适配实践:从资源、WebView 到网络图统一处理
harmonyos
看谷秀3 天前
鸿蒙-part3-arkts下
arkts
鸿蒙开发4 天前
鸿蒙(HarmonyOS NEXT)表单校验别再手撸正则了 —— 我写了个 ArkTS 版 zod
harmonyos
TrisighT4 天前
ArkTS 的 @BuilderParam 你八成只用了皮毛——那个尾随闭包写法差点被我当 bug 删了
harmonyos·arkts·arkui
ONEDAY4 天前
HarmonyOS 多 Product 构建实践:一套代码生成多个产物
harmonyos
TT_Close5 天前
别劝退了!5秒搞定 Flutter 鸿蒙 FVM 起跑线
flutter·harmonyos·visual studio code