基于递归Promise链实现带依赖关系的异步任务调度与结果返回
代码核心问题分析与修复方向
1. 任务ID取值错误
runTasks 方法中遍历任务ID时,错误对current取了下标[0]:
const taskResult = await runTaskWithDependencies( tasks, current[0], // 错误写法,current本身就是taskId字符串,不需要取[0] await previous );
这个错误会导致多字符的任务ID完全无法匹配,即使单字符ID暂时运行正常,逻辑上也是错误的,直接改为current即可。
2. 依赖完成判断逻辑完全写反
runTaskWithDependencies 中判断所有依赖是否执行完成的条件逻辑颠倒:
// 错误逻辑:要求results中所有的任务都属于当前任务的依赖,完全不符合需求 const allDependenciesExecuted = Object.keys(results).length > 0 && Object.keys(results).every((taskId) => taskDependencies.includes(taskId) );
正确的逻辑应该是当前任务的所有依赖ID,都已经存在于结果集results中,修改为:
const allDependenciesExecuted = taskDependencies.every(depId => Object.hasOwn(results, depId));
3. 循环依赖检测不完整
目前只检测了任务直接依赖自身的场景,没有覆盖间接循环依赖(比如a依赖b、b依赖a),会导致递归死循环。
你需要在递归过程中新增路径跟踪参数,记录当前递归链上的任务ID,一旦发现当前任务ID已经在路径中存在,就判定为循环依赖,直接标记为skipped。
4. 依赖结果合并丢失旧数据
处理依赖的分支中,跑完所有依赖的任务后,合并结果时从空对象开始,丢失了之前已经计算好的其他任务结果:
// 错误写法:初始值是{},旧的results内容完全丢失 ).reduce((previous, current) => { return { ...previous, ...current, }; }, {} as TaskResultDict);
修改为初始值传入当前的results,确保已有结果不丢失:
}, results as TaskResultDict);
同时注意,跑完依赖后你并没有执行当前任务本身的逻辑,直接返回了依赖的合并结果,会导致当前任务没有被处理,需要在合并完依赖结果后,再调用resolveDependency处理当前任务,再把当前任务的结果合并进去。
5. 未处理不在结果集里的依赖
resolveDependency中筛选未完成依赖时,只找了已经在results里的依赖,如果有依赖还没被处理、不在results里,就会被漏掉,导致应该标记为skipped的任务被错误执行。你需要先判断所有依赖是否都已经在results中存在,再筛选未成功resolve的依赖。
内容的提问来源于stack exchange,提问作者lbarrous
相关产品推荐
相关产品推荐

