假如有一个任务列表,每个任务项包含任务名称name和执行耗时time。形如
const tasks = [
{ name: 'a', time: 2000 },
{ name: 'b', time: 5000 },
{ name: 'c', time: 1000 },
{ name: 'd', time: 3000 },
{ name: 'e', time: 1000 },
{ name: 'f', time: 2000 },
{ name: 'g', time: 4000 }
]
要求实现一个函数进行任务调度,并能控制任务调度的并发数,最终能获取任务执行完成的顺序和总耗时
😊好巧不巧,之前在刷题的时候恰好思考过这个问题,面试的时候很顺利就写出来了。
递归实现
const request = (task) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(task)
}, task.time)
})
}
const handleTaskQueue = function (tasks = [], max = 3, callback = () => { }) {
const tasksLen = tasks.length;
const ret = [];
let index = 0;
const start = Date.now()
const queue = []
const run = function (task) {
const promise = request(task)
promise.then(res => {
const retLen = ret.push(res.name)
if (retLen < tasksLen && index + 1 < tasksLen) {
queue.splice(queue.indexOf(promise), 1)
run(tasks[++index])
} else if (retLen === tasksLen) {
'function' === typeof callback && callback({ ret, time: Date.now() - start })
}
})
if (queue.push(promise) < max) {
run(tasks[++index])
}
}
run(tasks[0])
}
handleTaskQueue(tasks, 2, (ret) => {
console.log(ret)
})
Promise.race实现
const request = (task) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(task)
}, task.time)
})
}
async function myAsyncPool(tasks = [], max = 3, callback = () => { }) {
let queue = [];
const ret = [];
const start = Date.now()
for (let i = 0; i < tasks.length; i++) {
const task = request(tasks[i])
task.then((data) => {
// 当任务执行完毕, 将其从正在执行任务数组中移除
ret.push(data.name)
console.log(`当前并发数: ${queue.length}`)
queue.splice(queue.indexOf(task), 1)
if (ret.length === tasks.length) {
'function' === typeof callback && callback({ ret, time: Date.now() - start })
}
})
queue.push(task)
if (queue.length === max) {
await Promise.race(queue)
}
}
}
myAsyncPool(tasks, 3, (ret) => { console.log(ret) })
打印输出
在处理任务耗时上比较粗糙,没(qi)有(shi)进(bu)行(hui)任务耗时精确计算😂