首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用promises实现JavaScript调度器

使用promises实现JavaScript调度器
EN

Stack Overflow用户
提问于 2018-08-15 05:51:04
回答 2查看 1.5K关注 0票数 2

我正在解决这个有趣的javascript问题(面试问题),我被困在如何使用promises实现这个问题上。

问题:

在JavaScript中编写一个调度器,它接受并发任务的最大数量作为参数,并调度任务(每个任务可能需要任意时间才能完成)。

请注意,在继续执行其他任务之前,我们一次只需要执行"n“(并发)任务。

这是我的实现:

代码语言:javascript
复制
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来实现这一点?在推动之前,我是否应该将一切都围绕在一个承诺周围?

有人能开导一下吗?

EN

回答 2

Stack Overflow用户

发布于 2018-08-15 06:58:10

因此,如果您可以从任务中返回promise,则可以绑定到promise的then(),以便在任务完成和可以启动另一个任务时提醒您。

这里有一个与您的类似的示例,但有一些变化:我们不关心队列的长度-您只想知道当前有多少活动作业。因此您可以在启动作业时递增active,在作业完成时递减它。

有很多方法,我肯定会这样做,但这里有一个想法的大纲:

代码语言:javascript
复制
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)

票数 6
EN

Stack Overflow用户

发布于 2020-02-22 15:57:52

window.addEventListener("load",function() { //这是没有承诺的

代码语言:javascript
复制
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();

});

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51850236

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档