```html
const sleep = (delay) => new Promise((r) => setTimeout(r, delay))
const tasks = {
a: {
job: async function () {
await sleep(1000)
console.log('Tasks A running')
},
dependency: ['c', 'b'],
},
b: {
job: async function () {
await sleep(3000)
console.log('Tasks B running')
},
dependency: [],
},
c: {
job: function () {
console.log('Tasks C running')
},
dependency: [],
},
d: {
job: function () {
console.log('Tasks D running')
},
dependency: ['c'],
},
}
function run(tasks) {
// ...Write your answer here
// The params `tasks` can be multiple of task, not just a、b、c、d. so don't answer with `a.job()` etc.
// Answer should not include keyword of a/b/c/d
}
run(tasks)
```
可以使用拓扑排序来解决该问题,基本思想是先遍历所有没有依赖关系的任务,再遍历它们的子任务,直到所有任务都被遍历完。
以下是一个基于该思想的实现:
function run(tasks) {
const taskNames = Object.keys(tasks)
const taskDepMap = {}
const taskDepCount = {}
const result = []
// 初始化任务依赖关系映射和依赖计数
taskNames.forEach((name) => {
const task = tasks[name]
taskDepMap[name] = task.dependency.slice()
const count = task.dependency.length
taskDepCount[name] = count
if (count === 0) {
result.push(name)
}
})
// 依次遍历每个任务,并执行
let i = 0
while (i < result.length) {
const name = result[i]
const task = tasks[name]
task.job()
// 更新子任务的依赖计数
taskDepMap[name].forEach((dep) => {
taskDepCount[dep]--
if (taskDepCount[dep] === 0) {
result.push(dep)
}
})
i++
}
}
以上代码首先初始化了任务依赖关系和依赖计数,然后按照依赖计数从小到大的顺序依次遍历任务,并执行任务的job()方法。在执行任务的job()方法后,还会更新子任务的依赖计数,并将依赖计数为0的任务添加到结果集中。
这样,就能够保证所有任务都能够按照正确的顺序执行。
-- 本次回答基于 chatgpt3.5