這道面試題論在當時我是寫不出來的,當時自吹熟悉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的數據問題(學長髮現的),若是實際應用的話,確定要恰數據的嘛,雖然原題沒有提到。
若是有小夥伴還有別的思路或者對缺點有思路的話歡迎評論