HarmonyOS 鸿蒙Next中taskpool任务依赖和promise回调时序
HarmonyOS 鸿蒙Next中taskpool任务依赖和promise回调时序
taskpool是否保证上一个依赖task的所有回调执行完,才执行依赖链下一个task
这里task1依赖task2,task2依赖task3,假如task2的执行需要task1的.then或者.catch内的执行结果,能否保证执行task2的时间在完成task1的.then之后
@Concurrent
function delay(args: number): number {
let t: number = Date.now();
while ((Date.now() - t) < 1000) {
continue;
}
return args;
}
let task1:taskpool.Task = new taskpool.Task(delay, 100);
let task2:taskpool.Task = new taskpool.Task(delay, 200);
let task3:taskpool.Task = new taskpool.Task(delay, 200);
console.info("dependency: add dependency start");
task1.addDependency(task2);
task2.addDependency(task3);
console.info("dependency: add dependency end");
console.info("dependency: start execute")
taskpool.execute(task1).then(() => {
console.info("dependency: task1 success");
})
taskpool.execute(task2).then(() => {
console.info("dependency: task2 success");
})
taskpool.execute(task3).then(() => {
console.info("dependency: task3 success");
})
更多关于HarmonyOS 鸿蒙Next中taskpool任务依赖和promise回调时序的实战教程也可以访问 https://www.itying.com/category-93-b0.html
【背景知识】
- TaskPool为应用程序提供多线程环境,降低资源消耗、提高系统性能,无需管理线程生命周期。TaskPool支持开发者在宿主线程提交任务到任务队列,系统选择合适的工作线程执行任务,再将结果返回给宿主线程。接口易用,支持任务执行、取消和指定优先级,同时通过系统统一线程管理,结合动态调度及负载均衡算法,可以节约系统资源。
- addDependency表示当前任务添加对其他任务的依赖。使用该方法前需先构造Task。该任务和被依赖的任务不能是任务组任务、串行队列任务、异步队列任务、已执行任务或周期任务。存在依赖关系的任务(依赖其他任务的任务或被依赖的任务)执行后不可再次执行。
【解决方案】
定义3个任务task1、task2、task3,依赖关系为task3->task2->task1;为了保证执行顺序为task3->task2->task1;使用addDependency接口建立各个任务之间的依赖关系达到任务的顺利执行。方案具体代码实现:
import { taskpool } from '@kit.ArkTS';
@Component
@Entry
struct TaskPoolDemo {
build() {
Column() {
Text('TaskTool多任务顺序执行')
}
}
aboutToAppear(): void {
let task1: taskpool.Task = new taskpool.Task(delay, 100);
let task2: taskpool.Task = new taskpool.Task(delay, 200);
let task3: taskpool.Task = new taskpool.Task(delay, 200);
console.info("dependency: add dependency start");
task1.addDependency(task2);
task2.addDependency(task3);
console.info("dependency: add dependency end");
console.info("dependency: start execute second");
taskpool.execute(task1).then(() => {
console.info("dependency: second task1 success");
})
taskpool.execute(task2).then(() => {
console.info("dependency: second task2 success");
})
taskpool.execute(task3).then(() => {
console.info("dependency: second task3 success");
})
}
}
@Concurrent
function delay(args: number): number {
let t: number = Date.now();
while ((Date.now() - t) < 1000) {
continue;
}
return args;
}
打印日志如下:
06-23 17:34:24.694 dependency: add dependency start
06-23 17:34:24.694 dependency: add dependency end
06-23 17:34:24.694 dependency: start execute second
06-23 17:34:25.990 dependency: second task3 success
06-23 17:34:26.990 dependency: second task2 success
06-23 17:34:27.991 dependency: second task1 success
更多关于HarmonyOS 鸿蒙Next中taskpool任务依赖和promise回调时序的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
你好,我其实想确认的是:依赖关系为task3->task2->task1,那么task2是在task3本身完成之后就可能开始执行,还是在task3的.then也全部完成之后才会开始执行,这种执行关系是有保证的吗。
从日志打印上就可以看出执行顺序:task3->task2->task1;每个task都是等then中回调函数执行完成,
2个问题:
其一:
通过addDependency
建立的依赖仅控制任务本体的执行顺序。你的示例中:
- task3 → task2 → task1 的执行顺序由依赖关系保证
- 每个任务的
execute()
方法会等待其所有依赖任务完成主逻辑后才会执行
代码执行顺序问题:
// 示例中三个任务实际执行顺序应为:task3 → task2 → task1
// 但代码中并行调用execute会导致依赖链失效
taskpool.execute(task1) // 应最后执行
taskpool.execute(task2) // 应第二个执行
taskpool.execute(task3) // 应第一个执行
正确的写法应为顺序提交任务:
taskpool.execute(task3).then(() => {
taskpool.execute(task2).then(() => {
taskpool.execute(task1)
})
})
其二: 回调执行机制:
.then
/.catch
回调属于微任务,会在主任务完成后按事件循环机制执行- 不保证在下一个依赖任务开始前完成
时序对比场景:
// 若task2需要task1的then回调结果
taskpool.execute(task1).then((result) => {
const modifiedResult = process(result) // 回调处理
// 此处需要显式触发task2执行
taskpool.execute(task2)
})
解决方案
// 正确方式:通过Promise链管理
taskpool.execute(task3)
.then(() => taskpool.execute(task2))
.then(() => taskpool.execute(task1))
.then(() => { /* 处理最终结果 */ })
验证
- 日志验证:
taskpool.execute(task3).then(() => {
console.log("task3完成时间戳:", Date.now())
})
taskpool.execute(task2).then(() => {
console.log("task2完成时间戳:", Date.now())
})
// 若两个时间戳接近或重叠,说明并行执行
- 线程ID检查:
@Concurrent
function logThreadId(args: number): number {
console.log("执行线程ID:", process.tid)
return args
}
// 通过观察输出可验证任务是否按预期顺序执行
您好,可以看一下以下两个方案:
多个任务同时执行时,由于任务复杂度不同,执行时间和返回数据的时间也会不同。如果宿主线程需要所有任务执行完毕的数据,可以通过TaskGroup的方式实现。
- 同步任务
同步任务是指在多个线程之间协调执行的任务,其目的是确保多个任务按照一定的顺序和规则执行,例如使用锁来防止数据竞争。
同步任务的实现需要考虑多个线程之间的协作和同步,以确保数据的正确性和程序的正确执行。
// Index.ets代码
import { taskpool} from '@kit.ArkTS';
// 步骤1: 定义并发函数,实现业务逻辑
@Concurrent
async function taskpoolFunc(num: number): Promise<number> {
// 根据业务逻辑实现相应的功能
let tmpNum: number = num + 100;
return tmpNum;
}
async function mainFunc(): Promise<void> {
// 步骤2: 创建任务并执行
let task1: taskpool.Task = new taskpool.Task(taskpoolFunc, 1);
let res1: number = await taskpool.execute(task1) as number;
let task2: taskpool.Task = new taskpool.Task(taskpoolFunc, res1);
let res2: number = await taskpool.execute(task2) as number;
// 步骤3: 对任务返回的结果进行操作
console.info("taskpool: task res1 is: " + res1);
console.info("taskpool: task res2 is: " + res2);
}
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.onClick(async () => {
mainFunc();
})
}
.width('100%')
.height('100%')
}
}
}
在鸿蒙Next中,taskpool任务依赖通过TaskGroup管理,支持addDependency()方法建立任务间依赖关系。Promise回调时序遵循JS标准规范:then()/catch()/finally()按注册顺序执行,但需注意微任务队列特性。任务池中的异步任务完成时会触发Promise回调,但跨线程任务需通过sendData()/postMessage()进行线程间通信。任务依赖的执行顺序优先于Promise回调链。
在HarmonyOS Next的taskpool中,任务依赖确实能保证执行顺序,但需要注意.then回调的执行时机。根据您提供的代码示例:
-
任务依赖关系:task1依赖task2,task2依赖task3,taskpool会严格按照task3→task2→task1的顺序执行这些任务。
-
Promise回调时序:taskpool.execute()返回的Promise回调(.then)是在主线程执行的,而任务本身是在工作线程执行的。因此:
- 任务本身的执行顺序是保证的(task3先于task2,task2先于task1)
- 但.then回调的执行时序取决于事件循环,不能保证task1.then一定在task2执行前完成
- 如果task2需要task1.then的结果,这种设计是不安全的。应该:
- 要么将依赖逻辑放在任务函数内部
- 要么通过Promise链式调用确保顺序
- 在您示例中,三个execute()是并行调用的,虽然依赖关系会保证任务执行顺序,但.then回调可能交错执行。
建议重构代码,使用单个execute()调用配合Promise链,或者将依赖逻辑移到任务函数内部,才能确保严格的执行顺序。