HarmonyOS 异步接口是否会启动一个子线程来执行其中的逻辑?

HarmonyOS 异步接口是否会启动一个子线程来执行其中的逻辑?

HarmonyOS
2024-11-25 10:57:31
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
put_get

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

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

以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-11-25 17:25:35
相关问题
销毁一个子窗口方法
410浏览 • 1回复 待解决
HarmonyOS 如何在class中启动一个线程
30浏览 • 1回复 待解决