我正在解决这个有趣的javascript问题(面试问题),我被困在如何使用promises实现这个问题上。
问题:
在JavaScript中编写一个调度器,它接受并发任务的最大数量作为参数,并调度任务(每个任务可能需要任意时间才能完成)。
请注意,在继续执行其他任务之前,我们一次只需要执行"n“(并发)任务。
这是我的实现:
var exampleTaskA = function () {
setTimeout(function () {
console.log('Task A Done');
}, 1000);
};
function TaskRunner(concurrency) {
this.limit = concurrency;
this.store = [];
this.len = this.store.length;
}
TaskRunner.prototype.push = function (task) {
this.store.push(task);
function getWorker(store, limit) {
if(!store.length) return;
if(store.length <= limit) {
const cur = store.shift();
if(cur) cur();
getWorker(store, limit);
}
}
getWorker(this.store, this.limit);
}
var task = new TaskRunner(2);
console.log(task.push(exampleTaskA));
console.log(task.push(exampleTaskA));
console.log(task.push(exampleTaskA));
console.log(task.push(exampleTaskA));
console.log(task.push(exampleTaskA));
console.log(task.push(exampleTaskA));
console.log(task.push(exampleTaskA));
如何使用promises / async await来实现这一点?在推动之前,我是否应该将一切都围绕在一个承诺周围?
有人能开导一下吗?
发布于 2018-08-15 06:58:10
因此,如果您可以从任务中返回promise,则可以绑定到promise的then()
,以便在任务完成和可以启动另一个任务时提醒您。
这里有一个与您的类似的示例,但有一些变化:我们不关心队列的长度-您只想知道当前有多少活动作业。因此您可以在启动作业时递增active
,在作业完成时递减它。
有很多方法,我肯定会这样做,但这里有一个想法的大纲:
const exampleTaskA = (name) => new Promise(resolve => setTimeout(function() {
console.log(`Task ${name} Done`);
resolve()
}, Math.floor(Math.random() * 2000)))
function TaskRunner(concurrency) {
this.limit = concurrency;
this.store = [];
this.active = 0;
}
TaskRunner.prototype.next = function() {
if (this.store.length) this.runTask(...this.store.shift())
}
TaskRunner.prototype.runTask = function(task, name) {
this.active++
console.log(`Scheduling task ${name} current active: ${this.active}`)
task(name).then(() => {
this.active--
console.log(`Task ${name} returned, current active: ${this.active}`)
this.next()
})
}
TaskRunner.prototype.push = function(task, name) {
if (this.active < this.limit) this.runTask(task, name)
else {
console.log(`queuing task ${name}`)
this.store.push([task, name])
}
}
var task = new TaskRunner(2);
task.push(exampleTaskA, 1)
task.push(exampleTaskA, 2)
task.push(exampleTaskA, 3)
task.push(exampleTaskA, 4)
task.push(exampleTaskA, 5)
task.push(exampleTaskA, 6)
task.push(exampleTaskA, 7)
发布于 2020-02-22 15:57:52
window.addEventListener("load",function() { //这是没有承诺的
function Task(name) {
this.isDone = false;
this.name = name;
}
Task.prototype.run = function() {
setTimeout(()=>{
this.isDone = true;
}, 3000);
}
function TaskScheduler(limit) {
this.limit = limit;
this.active = 0;
this.pendingTasks = [];
this.runningTasks = [];
}
TaskScheduler.prototype.runTask = function(task) {
this.active++;
task.run();
}
TaskScheduler.prototype.init = function() {
var interval = setInterval(() => {
// check and clean running tasks
this.runningTasks = this.runningTasks.filter((task) => {
if (task.isDone) {
this.active--;
}
return !task.isDone;
});
while(this.pendingTasks.length) {
if (this.active < this.limit) {
var task = this.pendingTasks.pop();
this.runTask(task);
this.runningTasks.push(task);
} else {
break;
}
}
if (!this.pendingTasks.length) {
clearInterval(interval);
}
}, 0);
}
TaskScheduler.prototype.push = function(task) {
this.pendingTasks.push(task);
}
var taskSecheduler = new TaskScheduler(2);
taskSecheduler.push(new Task(1));
taskSecheduler.push(new Task(2));
taskSecheduler.push(new Task(3));
taskSecheduler.push(new Task(4));
taskSecheduler.push(new Task(5));
taskSecheduler.push(new Task(6));
taskSecheduler.init();
});
https://stackoverflow.com/questions/51850236
复制相似问题