1224 今日总结
今日计划
每天工作前/前一天晚上 做好计划:重点工作、自我提升、其他
重点工作
- 房源列表页
- 昨天的 上传组件问题处理
自我提升
- React 事件系统复习
- 整体复习:https://mp.weixin.qq.com/s/lXWWV3f0uYvNGkdwfyjACg
其他
今日总结
问题,原因,解决方式,优化,巧妙实现,新知识
手撕代码/算法
防抖节流等各种手写,http 和网络,浏览器原理,性能优化,Webpack
字节面试题:JS 实现一个带并发限制的异步调度器 Scheduler
js
class Scheduler {
constructor() {}
add() {}
}
const timeout = (time) => new Promise((resolve) => setTimeout(resolve, time))
const scheduler = new Scheduler() // 并发限制为 2
const addTask = (time, order) => {
scheduler.add(() => timeout(time).then(() => console.log(order)))
}
addTask(1000, 1)
addTask(500, 2)
addTask(300, 3)
addTask(400, 4)
scheduler.start()
// output: 2 3 1 4
// 一开始,1、2两个任务进入队列
// 500ms时,2完成,输出2,任务3进队
// 800ms时,3完成,输出3,任务4进队
// 1000ms时,1完成,输出1
// 1200ms时,4完成,输出4
答案:
js
class Scheduler {
constructor(limitNum) {
this.limitNum = limitNum
this.queue = []
this.runningNum = 0;
}
add(taskFn) {
this.queue.push(taskFn);
}
start() {
for (let i = 0;i < this.limitNum;i++) {
this.excute()
}
}
excute() {
if (this.queue.length && this.runningNum < this.limitNum) {
this.runningNum++
const fn = this.queue.shift();
fn().then(() => {
this.runningNum--;
this.excute();
})
}
}
}
const timeout = (time) => new Promise(resolve => setTimeout(resolve, time))
const scheduler = new Scheduler(2) // 并发限制为 2
const addTask = (time, order) => {
scheduler.add(() => timeout(time).then(() => console.log(order)))
}
addTask(1000, 1)
addTask(500, 2)
addTask(300, 3)
addTask(400, 4)
scheduler.start()
// output: 2 3 1 4
// 一开始,1、2两个任务进入队列
// 500ms时,2完成,输出2,任务3进队
// 800ms时,3完成,输出3,任务4进队
// 1000ms时,1完成,输出1
// 1200ms时,4完成,输出4
分析:主要有几个地方需要注意
- 控制器 预执行队列 start 和 真正的执行队列 excute 需要分开;
- 已执行完的 fn,在 fn.then(() => { /.../}) 进行状态控制,如 this.runningNum 的变化
- 边界控制:队列 queue 的长度,限制数量的最大值,运行的 fn;
相关参考资料:
- 面试题:实现一个输入url数组与并发数的并发数量控制请求队列函数。
- https://juejin.cn/post/6956826374677987336
- https://cloud.tencent.com/developer/article/1661044
- https://juejin.cn/post/6975424125980377118
- https://github.com/Yuanyuanyuanc/aYuan-learning-notes/issues/2
好文推荐/面经相关/博客项目推荐
有感好文,面经,博客,项目等