one_day
@one_day

Как выполнить функции в порядке очереди, в которых содержатся таймеры?

Необходимо их выполнить так, чтобы каждая следующая начиналась после того как полностью отработают таймеры из предыдущей
не смог ,к сожалению, сам разобраться с данной задачей
после выполнения функций должен сформировать массив: ["hello world", "Job succeded", "step3", "step4"]
но из-за таймеров получаю: ["step4", "hello world", "Job succeded", "step3"]
читаю про Deferred, как их применить конкретно на данной задаче все не придумаю
ссылка в codepen
код 1
<script>
var results=[];
function Parallel(setings,step,done) {
this.parallelJobs = setings;

this.job = function (step){
    step(function done(message) {
            results[results.length] = message;    
    });
    return this;
};
this.done = function (done) {
    done(results);
    return this;
};
};
</script></spoiler>

этот участок кода не могу править
код 2
<script>
    /************************************************
     * Please don`t change the code bellow this line *
     ************************************************/
	 
    var runner = new Parallel({
		//the number of simultaneously possible jobs, other jobs should be placed in queue.
        parallelJobs: 2
    });

    runner.job(step1)
        .job(step2)
        .job(step3)
        .job(step4)
        .done(onDone);

    function step1(done) {
        console.log('step1');
        for ( let i = 0; i <= 10e4; i++ ) ;
        console.log('end step1 cicle');
        setTimeout(done, 1000, 'hello world');
    }

    function step2(done) {
        console.log('step2');
        for ( let i = 0; i <= 10e2; i++ ) ;
        console.log('end step2 cicle');
        setTimeout(done, 1200, 'Job succeded');
    }

    function step3(done) {
        console.log('step3');
        for ( let i = 0; i <= 10e3; i++ ) ;
        console.log('end step3 cicle');
        setTimeout(done, 1500, 'step3');
    }

    function step4(done) {
        console.log('step4');
        for ( let i = 0; i <= 10e1; i++ ) ;
        console.log('end step4 cicle');
        setTimeout(done, 100, 'step4');
    }

    var isPassed = false;

    function onDone(results) {
        console.log('onDone', results);
        console.assert(Array.isArray(results), 'expect result to be array');
        console.assert(results[0] === 'hello world', 'Wrong answer 1');
        console.assert(results[1] === 'Job succeded', 'Wrong answer 2');
        console.assert(results[2] === 'step3', 'Wrong answer 3');
        console.assert(results[3] === 'step4', 'Wrong answer 4');
        console.log('Thanks, all works fine');
        isPassed = true;
    }

    setTimeout(function () {
        if ( isPassed ) return;
        console.error('Test is not done.');
    }, 10000);
</script>
ссылка в codepen
  • Вопрос задан
  • 250 просмотров
Решения вопроса 1
rockon404
@rockon404
Frontend Developer
Вот:
function Parallel(settings) {
  this.parallelJobs = settings.parallelJobs;
  this.results;
  this.tasks = [];
  this.onDone;
  this.index = 0;
  this.activeJobs = 0;
  
  this.start = function() {
    this.results = Array(this.tasks.length);
    
    for (var i = 0; i < Math.min(this.parallelJobs, this.tasks.length); i++) {
      this.next();
    }
  }
  
  this.next = function(result) {
      var index = this.index;
      this.activeJobs++;
     

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

      this.index++;
  }
  
  this.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);
    }
  }
  
  this.job = function (step) {
    this.tasks.push(step);
    return this;
  };
  
  this.done = function (onDone) {
     this.onDone = onDone;
     this.start();
  };
};


Демо: https://jsfiddle.net/rockon404/thL746dd/
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@Coder321
class Queue {

    queue = [];
    isRunning = false;

    add(task) {
        queue.push(task);
        if (!this.isRunning) {
            this.start();
        }

    }

    async start() {
        this.isRunning = true;
        for (let i = 0; i < this.queue.length; i++) {
            await this.queue[i]();
        }
        this.isRunning = false;
    }

}

const queue = new Queue();

queue.add(() => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            //your timer
        }, 1000)
    });
})
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы