D
D
DarthJS2018-02-04 14:04:12
JavaScript
DarthJS, 2018-02-04 14:04:12

How to control the number of simultaneous calls to asynchronous functions in the queue?

The bottom line is that it is impossible to control the queue with the specified parameter. Below, I push callbacks into the queue, which I can either loop through or just use Resolve.all, but when there is a parameter, for example, you need to execute no more than two or three functions, you can’t wait.
Let's say we have an asynchronous function and a constructor:

function asynRequest(result) {  // наша асинхронная функция
     setTimeout(result, 2000, 'data');
}

function Foo (params) { // наш конструктор
this.count = params.count // число одновременных вызовов
this.queue = []; // наша будущая очередь
this.working = 0; // параметр, который говорит сколько функций обрабатывается
}

Foo.prototype.tick = function (callback) {
      this.queue.push(callback); // добавляем 
      return this;
}

Foo.prototype.resolver = function () {
    var vm = this;
     this.queue.forEach(function (cb) {  // Тут что бы я не делал у меня выходит либо Max call stack либо просто не 
     получается вернуть проми с результатами. 
     vm.working++;
     });
     return Promise.resolve();
}

Foo.prototype.finish = function () {
       this.resolver().then(function (response) {
       console.log('УРААА!!', response)
       });
}

var executor = new Foo({count: 2});
executor
 .tick()
 .tick()
 .tick()
 .finish()

I understand that I'm trying to use the wrong approach. Maybe there are patterns to solve this problem that I could not find.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Anton Spirin, 2018-02-05
@DarthJS

function Parallel(settings) {
  this.parallelJobs = settings.parallelJobs;
  this.results;
  this.tasks = [];
  this.onDone;
  this.index = 0;
  this.activeJobs = 0;
};

Parallel.prototype.start = function() {
  this.results = Array(this.tasks.length);

  for (var i = 0; i < Math.min(this.parallelJobs, this.tasks.length); i++) {
    this.next();
  }
}

Parallel.prototype.next = function(result) {
  var index = this.index;
  this.activeJobs++;


  this.tasks[this.index](function(result) {
    this.onResult(result, index);
  }.bind(this));

  this.index++;
}

Parallel.prototype.onResult = function(result, index) {
  this.results[index] = result;
  this.activeJobs--;

  if(this.tasks[this.index]) {
    this.next();
  } else if (this.activeJobs === 0) {
    this.onDone(this.results);
  }
}

Parallel.prototype.job = function (step) {
  this.tasks.push(step);
  return this;
};

Parallel.prototype.done = function (onDone) {
  this.onDone = onDone;
  this.start();
};



function asyncRequest1(result) {  
     setTimeout(result, 2000, 'data');
}

function asyncRequest2(result) {  
     setTimeout(result, 2000, 'data 2');
}

function asyncRequest3(result) {  
     setTimeout(result, 2000, 'data3');
}

function asynRequest4(result) {  
     setTimeout(result, 2000, 'data4');
}



var runner = new Parallel({
  parallelJobs: 2
});

runner.job(asyncRequest1)
      .job(asyncRequest2)
      .job(asyncRequest3)
      .job(asyncRequest4)
      .done(function (results) {
         console.log(results); 
      });

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question