предисловие
Я не мог написать этот вопрос для интервью в то время. В то время я хвастался, что знаком с промисами. Было немного неловко писать этот вопрос. Это.
Последующее собеседование не было завершено, потому что стажер дропа уже был нанят до собеседования.
тема
//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
// 一开始,1、2两个任务进入队列
// 500ms时,2完成,输出2,任务3进队
// 800ms时,3完成,输出3,任务4进队
// 1000ms时,1完成,输出1
// 1200ms时,4完成,输出4
рабочий процесс
Левое значение @ — это оставшееся время, а правое значение — это выходное содержимое.
| Очередь выполнения (максимум две) | очередь ожидания | поведение | содержание исполнения |
|---|---|---|---|
| 1000@1 | Если очередь выполнения не заполнена, войдите в очередь выполнения напрямую. | addTask(1000, '1') | |
| 1000@1, 500@2 | Если очередь выполнения не заполнена, войдите в очередь выполнения напрямую. | addTask(500, '2') | |
| 1000@1, 500@2 | 300@3 | Очередь выполнения заполнена, присоединяйтесь к очереди ожидания | addTask(300, '3') |
| 1000@1, 500@2 | 300@3, 400@4 | Очередь выполнения заполнена, присоединяйтесь к очереди ожидания | addTask(400, '4') |
| 500@1, 300@3 | 400@4 | 500@2 выполняется и выводит 2, 1000@1 потребляет 500 и добавляется в очередь выполнения по порядку из очереди ожидания | |
| 200@1, 400@4 | Выполнение 300@3 завершает вывод 3, 500@1 потребляет 300 и добавляется в очередь выполнения по порядку из очереди ожидания | ||
| 200@4 | 200@1 завершение выполнения, выход 1 | ||
| 200@4 выполнение завершено, выход 4 |
идеи
Обратите внимание, что то, что передается в методе добавления, является функцией и возвращает обещание. Это сложный момент. Многие люди меняют вопрос. Я видел, как он написан с помощью геттеров и сеттеров. Я думаю, что это отличается от предмета, который нужно протестировать. .
С первыми двумя легко справиться, напрямую определить, заполнена ли очередь выполнения, и напрямую войти в очередь, если она не заполнена.
Для третьего и более поздних вам нужно судить, разрешены ли первые два.Обратите внимание, что концепции первых двух и первых двух различаются (поскольку это уровень абстракции, вот пример: в настоящее время в третьем, затем первое из первых двух относится к первому к первому, последнее относится ко второму; в настоящее время в четвертом, затем первое из первых двух относится к первому ко второму, последнее относится к третьему; и и т. д.), после разрешения Добавить в очередь выполнения по порядку из очереди ожидания.
Этому есть две причины. Первое выполняется первым, то есть все задачи в коллекции выполнены, затем вторые обязательно поступают в исполнение (незавершенные), затем в очереди на выполнение остается позиция; вторые завершаются первыми, остается нечего сказать об этом, последнее Обязательно останется одно место, когда вы закончите.
код
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;
}
}
Слабые стороны и слабости
-
нельзя использовать повторно
Если максимальное количество очередей выполнения настроено на 3 или более, необходимо определить, есть ли разрешение в первых n
-
склонность к взрыву памяти
Список всегда выполнял обещания, будь то решенные или ожидающие решения.
-
Обработка исключений
Вопросы в разделе комментариев
В принципе, идеи всех областей комментариев схожи. Кроме того, есть тот факт, что большинство людей не рассматривали проблему с данными исходного обещания (найденного старшими), если оно действительно применяется, это должны быть данные, хотя в исходном вопросе об этом не упоминалось.
наконец
Если у вас есть другие идеи или идеи для недостатков, пожалуйста, прокомментируйте