在JavaScript中使用并发创建异步任务跑者
#javascript #scheduler #并发性 #async

让我们考虑我们需要在JavaScript中创建AYNC任务跑步者,并具有以下约束:

  1. 任务跑步者应具有一组将被推到它的任务,
  2. 这些任务中的每一个都将是一些异步操作,
  3. 任务跑步者还应确保在单个时间点只能执行一个给定数量的任务,而其他任务则不断等待,除非他们的任务出现。

让我们首先编码解决方案

class Runner{
      constructor(concurrency=1){
          this.concurrency = concurrency;
          this.waitList = [];
          this.count = 0;
          this.currentQ = [];
      }
      push(task){
         this.waitList.push(task);
         this.run();
      }
      run(){
         let current = this;
         if(this.count<this.concurrency){
            this.count++;
            if(this.waitLength>0){
               let task = this.waitList.shift();
               let id = task.id;
               this.currentQueue.push(id);
               this.showRunningTasks();
               let done = function(){ 
       this.currentQueue.splice(this.currentQueue.indexOf(id),1);
                  this.showRunningTasks();
                  this.count = this.count - 1;
                  this.run();
               }.bind(current);
               task.task(done);
            }
         }
      }

      showRunningTasks(){
         let existingQueue = this.currentQueue.join(", ");
         document.getElementId("running").innerHTML = existingQueue;
      }
}

Image description

让我们逐行理解这条代码。

  1. 最初,我们通过concurrencyflag,指示可以同时运行多少个任务。 waitList用于制作任务的等待列表,除非称为currentQueue的队列为空,否则该任务将等待。初始化了count变量以计算并发任务的数量。

  2. push方法用于将任务推向waitList,然后我们执行运行方法。这仅表示如果队列为空,则需要运行任务

  3. 运行方法很有趣。首先,它通过表示为let current = this

  4. 的第一行保留任务的上下文
  5. 接下来,我们检查并发性,如果候补名单有元素,我们简单地,

  • 将任务ID推到Currentqueue,
  • 通过方法showRunningTasks显示当前运行任务,
  • 在内部donemethod中,将被视为回调 在任务中,我们简单地从当前的ID中删除任务
    队列
    减少计数以减少并发任务的总数
  • 最后,我们递归调用Run()方法以运行 当前功能。请注意,这里的上下文保持不变。
  • 最后,我们将此功能绑定到当前上下文。
  • 我们将此函数传递给任务.task函数。

现在让我们看看如何使用此方法

使用以下代码段查看结果。

let runner = new Runner(3);
let task1 = {
  id: 1,
  task: function(done) {
    setTimeout(function() {
      console.log("Task 1");
      done();
    }, 3000)
  }
}

let task2 = {
  id: 2,
  task: function(done) {
    setTimeout(function() {
      console.log("Task 2");
      done();
    }, 5000)
  }
}

let task3 = {
  id: 3,
  task: function(done) {
    setTimeout(function() {
      console.log("Task 3");
      done();
    }, 4000)
  }
}

let task4 = {
  id: 4,
  task: function(done) {
    setTimeout(function() {
      console.log("Task 4");
      done();
    }, 9000)
  }
}

runner.push(task1);
runner.push(task2);
runner.push(task3);
runner.push(task4);

您将在屏幕上看到结果1,任务3,任务2,任务4 ,这是可以预期的。