整理下初学时做过的js基础编程题目和大家分享以下,如果大家觉得有用,别忘了点一下赞哦
题目内容
/**
* Q: 实现一个异步任务执行器 AsyncWorker
*
* 此 AsyncWorker: 最多只能同时执行 capacity
* 个异步任务. 若正在执行的任务数达到 capacity,
* 则新加入的任务需要等待其中一个正在执行的任务完
* 成后才能被执行.
*/
代码区
class AsyncWorker {
constructor(capacity) {
this.capacity = capacity
}
exec(task) {
// show me the code, please delete the following line.
throw new Error('not implemented')
}
}
// TEST
async function testAsyncWorker() {
const start = Date.now()
const createTask = (timeout, error) => {
return () =>
new Promise((resolve, reject) => {
setTimeout(() => {
if (error) {
reject(error)
} else {
resolve(timeout)
}
}, timeout)
})
}
const worker = new AsyncWorker(2)
const tasks = [
{
status: 'fulfilled',
value: 100,
idealCost: 100,
task: worker.exec(createTask(100)),
},
{
status: 'fulfilled',
value: 201,
idealCost: 200,
task: worker.exec(createTask(201)),
},
{
status: 'rejected',
reason: 'REJECTED',
idealCost: 300,
task: worker.exec(createTask(202, 'REJECTED')),
},
{
status: 'fulfilled',
value: 203,
idealCost: 400,
task: worker.exec(createTask(203)),
},
{
status: 'fulfilled',
value: 300,
idealCost: 600,
task: worker.exec(createTask(300)),
},
]
for (let index = 0; index < tasks.length; index++) {
const t = tasks[index]
let result
try {
const value = await t.task
result = { status: 'fulfilled', value }
} catch (e) {
result = { status: 'rejected', reason: e }
}
const realCost = Date.now() - start
const idealCost = (realCost - (realCost % 100)) | 0
if (idealCost !== t.idealCost) {
throw new Error(
`unexpected time cost: ${idealCost}, expected is ${t.idealCost} for ${index}`
)
}
if (result.status !== t.status) {
throw new Error(`unexpected status ${result.status} for ${index}`)
}
if (
t.status === 'fulfilled' &&
result.status === 'fulfilled' &&
result.value !== t.value
) {
throw new Error(
`unexpected fulfilled value ${result.value}, expected is ${t.value} for ${index}`
)
}
if (
t.status === 'rejected' &&
result.status === 'rejected' &&
result.reason !== t.reason
) {
throw new Error(
`unexpected rejected reason ${result.reason}, expected is ${t.reason} for ${index}`
)
}
}
}
思路
待续...
答案
class AsyncWorker {
constructor(capacity) {
this.capacity = capacity
this.taskNum = 0 // 当前任务数量
this.taskPool = [] // 回调函数队列池
}
exec(task) {
return new Promise((resolve, reject) => {
const execute = () => {
this.taskNum++; // 增加正在执行的任务数
task()
.then(result => {
resolve(result); // 成功时解析 Promise
})
.catch(error => {
reject(error); // 失败时拒绝 Promise
})
.finally(() => {
this.taskNum--; // 减少正在执行的任务数
this.processQueue(); // 处理等待队列中的任务
})
};
if (this.taskNum < this.capacity) {
execute(); // 如果有可用的执行容量,立即执行任务
} else {
this.taskPool.push(execute); // 否则将任务添加到等待队列
}
});
}
processQueue() {
if (this.taskPool.length > 0 && this.taskNum < this.capacity) {
const task = this.taskPool.shift(); // 从等待队列中获取下一个任务
task(); // 执行等待的任务
}
}
}