这道面试题论在当时我是写不出来的,当时自吹熟悉promise结果这道题写不粗来有点尴尬哈哈,面试结束后面试官官让我再让我想一下(大概下一面会再考),目前这个写法大概消耗了一下午的时间去思考吧。javascript
这场面试后续没完成,由于面以前就已经入职某滴的实习生了。java
//JS实现一个带并发限制的异步调度器Scheduler,保证同时运行的任务最多有两个。完善代码中Scheduler类,使得如下程序能正确输出
class Scheduler {
add(promiseCreator) { ... }
// ...
}
const timeout = (time) => new Promise(resolve => {
setTimeout(resolve, time)
})
const scheduler = new Scheduler()
const addTask = (time, order) => {
scheduler.add(() => timeout(time))
.then(() => console.log(order))
}
addTask(1000, '1')
addTask(500, '2')
addTask(300, '3')
addTask(400, '4')
// output: 2 3 1 4
// 一开始,一、2两个任务进入队列
// 500ms时,2完成,输出2,任务3进队
// 800ms时,3完成,输出3,任务4进队
// 1000ms时,1完成,输出1
// 1200ms时,4完成,输出4
复制代码
@左值为剩余时间,右值为输出内容面试
执行队列(最大两个) | 等待队列 | 行为 | 执行内容 |
---|---|---|---|
1000@1 | 执行队列未满,直接进入执行队列 | addTask(1000, '1') | |
1000@一、500@2 | 执行队列未满,直接进入执行队列 | addTask(500, '2') | |
1000@一、500@2 | 300@3 | 执行队列已满,加入到等待队列 | addTask(300, '3') |
1000@一、500@2 | 300@三、400@4 | 执行队列已满,加入到等待队列 | addTask(400, '4') |
500@一、300@3 | 400@4 | 500@2执行完成输出2,1000@1消耗掉500,从等待队列按序加入到执行队列 | |
200@一、400@4 | 300@3执行完成输出3,500@1消耗掉300,从等待队列按序加入到执行队列 | ||
200@4 | 200@1执行完成输出1 | ||
200@4执行完成输出4 |
注意add方法里面传入的是函数并返回Promise,这是难点,不少人都是改题,我见过拿getter、setter写的,我以为跟题目要考的主旨不一样。promise
前两个很好处理,直接判断执行队列中是否满员,未满直接进队并发
第三个及之后则须要判断前二者是否resolve,注意这里前二者和前两个的概念不一样(因为是一层抽象,这里举例说明:目前处于第三个,那么前二者的前者指第一个到第一个,后者指第二个;目前处于第四个,那么前二者的前者指第一个到第二个,后者指第三个;以此类推),resolve后从等待队列按顺序加入到执行队列。异步
说下缘由,有两种状况。前者先完成,也就是集合中的任务所有执行完成,那么后者必定会进入执行(未完成),那么执行队列中必定会剩下一个位置;后者先完成,这个没什么可说的,后者完成后必定会剩下一个位置。函数
class Scheduler {
constructor() {
this.list=[] //promise list
this.cur=0 //current position
this.max=2
}
add(promiseCreator) {
let temp=null;
if(this.cur < this.max) {
temp=promiseCreator();
}else {
let arr=this.list.slice(0,this.cur-1);
let all=Promise.all(arr);
temp=Promise.race([all,this.list[this.cur-1]])
.then(() => {
return promiseCreator();
});
}
this.list.push(temp);
this.cur++;
return temp;
}
}
复制代码
没法复用ui
若是调整为执行队列最大个数为3或以上,则须要判断前n者中是否有resolvethis
容易内存爆炸spa
list一直保存着primise,不管resolve仍是pedding
异常处理
基本上全部评论区的的思路都是差很少的。而后就是大部分人没有考虑抛出原promise的数据问题(学长发现的),若是实际应用的话,确定要恰数据的嘛,虽然原题没有提到。
若是有小伙伴还有别的思路或者对缺点有思路的话欢迎评论