ArkTS异步机制与执行顺序

ArkTS异步机制与执行顺序

HarmonyOS
2024-06-11 20:25:24
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
savan

异步机制

ArkTs仅在单线程(主线程)上执行任务,其异步机制与JavaScript一致,都是通过宿主环境提供的携程实现(napi,其接口与nodejs一致),即通过EventLoop实现。

EventLoop

EventLoop负责循环监视调用堆栈和回调队列,如果调用堆栈为空,它将从回调队列中获取第一个事件,并将其推送到调用堆栈。

以setTimeout为例:

console.log('Hi'); 
setTimeout(function cb1() {  
    console.log('cb1'); 
}, 5000); 
console.log('Bye');

执行顺序:

  • console.log('Hi'); 该语句被添加到调用堆栈中,随着执行完,被移除调用堆栈;
  • setTimeout(function cb1() { ... });该语句首先被添加到调用堆栈,被执行时,宿主环境创建了一个计时器,为代码计时。当该语句被执行完,会被移除调用堆栈。
  • 等待至少5000ms,定时器执行完,把cb1回调函数添加到回调队列里面,EventLoop把cb1从回调队列中取出,添加到调用堆栈中。

注意,setTimeout中设置的时间,是计时器过期时将回调放入回调队列的时间,而不是回调函数被执行的时间(只有调用栈是空的,EventLoop才会从调用栈中取)

执行顺序

与JavaScript一样,AkrTs也存在宏任务(Macrotask)队列和 微任务(Microtask)队列。宏任务例如setTimeout、setInterval,微任务例如普通回调函数,Promise相关函数等。

其执行顺序为:

  • 从 宏任务 队列中出队并执行最早的任务(只执行一个);
  •  执行所有微任务

− 当微任务队列非空时:

− 出队(dequeue)并执行最早的微任务;

− 继续检查微任务队列空不空(即执行完所有的微任务,新创建的微任务会立即进入微任务队列排队执行,不需要等待下一次轮回);

  • 如果有变更,则将变更渲染出来;
  • 如果宏任务队列为空,则休眠直到出现宏任务;
  • 转到步骤 1。

举例

setTimeout(() => hilog.debug(0, TAG, "timeout")); 
​ 
new Promise<void>((resolve, reject) => { 
    hilog.debug(0, TAG, "resolve"); 
    resolve(); 
}) 
    .then(() => hilog.debug(0, TAG, "promise")); 
​ 
hilog.debug(0, TAG, "code");

执行顺序:

  •  resolve最先显示,因为Promise内的代码也是同步执行;
  •  code 接着显示,因为它是常规的同步调用;
  •  promise 第二个出现,因为 then 会通过微任务队列,并在当前代码之后执行;
  • timeout 最后显示,因为它是一个宏任务。
分享
微博
QQ
微信
回复
2024-06-12 17:01:14
相关问题
如何获知TaskPool执行顺序、优先级?
290浏览 • 0回复 待解决
组件状态修改build渲染机制
324浏览 • 1回复 待解决
ArkTs异步方法如何转变成同步方法
565浏览 • 0回复 待解决
如何确保执行顺序,是否需要加锁
447浏览 • 1回复 待解决
ArkTSC++互相直接调用
469浏览 • 1回复 待解决
ArkTS层实例化单例介绍
511浏览 • 1回复 待解决
ArkTS在代码执行效率是如何提升的
631浏览 • 1回复 待解决
如何在ArkTS代码中执行HTML内的JS函数
812浏览 • 1回复 待解决
H5页面如何ArkTS交互
1315浏览 • 1回复 待解决