Как создать синхронизированный l oop на основе переменных в других циклах? - PullRequest
2 голосов
/ 20 апреля 2020

Я пытаюсь создать синхронизированный l oop, который выполняет итерацию по массиву объектов и запускает таймер на основе значения key: в каждом объекте. Для простоты я вызвал только консольный журнал в функциях. Мне нужно выполнить следующие шаги:

  • таймер регистрирует первый элемент в списке после вызова
  • , затем таймер регистрирует обратный отсчет в секундах, начиная со значения времени первых элементов и регистрируя новое время каждую секунду.
  • когда время достигает 0, происходит обратный отсчет, равный переменной ожидания.
  • следующий элемент регистрируется, затем повторяется шаг обратного отсчета и ожидания а затем переходит к следующему элементу в списке повторяющихся.

Вот код без каких-либо таймеров:

const list = [{
        item: 'Item 1',
        time: 30
    },
    {
        item: 'Item 2',
        time: 25
    },
    {
        item: 'Item 3',
        time: 40
    }
];

const wait = 5;

function logger(input, suffix) {
    console.log(`${input} ${suffix}`)
}

function runTimer() {
    logger(list[0].item, 'timer')
    for (let i = 0; i < list.length; i++) {
        logger(list[i].item, 'timer');
        for (t = list[i].time; t > 0; t--) {
            logger(t, 'seconds');
        }
        for (let w = wait; w > 0; w--) {
            logger(w, 'secs wait')
        }
    }
};

runTimer();

Я могу получить правильный порядок журнала, но я изо всех сил пытаюсь получить правильное время, я теряюсь в вызове setTimeouts в течение нескольких временных циклов. Как я могу это сделать?

Ответы [ 2 ]

2 голосов
/ 20 апреля 2020

Я бы предложил вам использовать цепочку Promises для реализации этого. Вы можете начать с создания общей функции countdown, которая возвращает Promise:

function countdown(time, msg) {
  return new Promise(resolve => {
    const i = setInterval(() => {
      logger(time, msg);
      if (time === 0) { // the promise resolves once the time reaches 0
        clearInterval(i);
        resolve();
      }
      time--;
    }, 1000);
  });
}

Затем вы можете использовать эту функцию, чтобы объединить счетчик каждого элемента со временем ожидания:

function runTimer () {
  let p = Promise.resolve();
  for (let i of list) {
    p = p.then(() => countdown(i.time, i.item).then(() => countdown(wait, 'wait')));
  }
  p.then(() => console.log('done!'));
};

Вот полный пример:

const list = [
  {
    item:'Item 1',
    time:3
  },
    {
    item:'Item 2',
    time:5
  },
    {
    item:'Item 3',
    time:4
  }
];

const wait = 5;

function logger(input, suffix) {
  console.log(`${input} ${suffix}`)
}

function runTimer () {
  let p = Promise.resolve();
  for (let i of list) {
    p = p.then(() => countdown(i.time, i.item).then(() => countdown(wait, 'wait')));
  }
  p.then(() => console.log('done!'));
};

function countdown(time, msg) {
  return new Promise(resolve => {
    const i = setInterval(() => {
      logger(time, msg);
      if (time === 0) {
        clearInterval(i);
        resolve();
      }
      time--;
    }, 1000);
  });
}

runTimer();
0 голосов
/ 20 апреля 2020

Надеюсь, это поможет!

const list = [ {
            item:'Item 1',
            time:5
        },
        {
            item:'Item 2',
            time:3
        },
        {
            item:'Item 3',
            time:6
        }
    ];

    const wait = 5;

    let itemCounter = 0;
    runTimer();

    function runTimer() {
        //  Timer for each item in list
        console.log(list[itemCounter].item+ " timer");

        var timer = list[itemCounter].time;
        var interval = setInterval(function() {

            var minutes = parseInt(timer / 60, 10),
                seconds = parseInt(timer % 60, 10);

            minutes = minutes < 10 ? "0" + minutes : minutes;
            seconds = seconds < 10 ? "0" + seconds : seconds;

            console.log(minutes+ " : " +seconds);

            if(timer-- <= 0) {
                clearInterval(interval);
                waitTimer(); 
            }            
        }, 1000);
    }

    function waitTimer() {
        //  Timer for "wait time" after an Item timer is complete
        var timer = wait;
        console.log("Wait timer after "+list[itemCounter].item+" timer")
        var interval = setInterval(function() {

            var minutes = parseInt(timer / 60, 10),
                seconds = parseInt(timer % 60, 10);

            minutes = minutes < 10 ? "0" + minutes : minutes;
            seconds = seconds < 10 ? "0" + seconds : seconds;

            console.log(minutes+ " : " +seconds);

            if(timer-- <= 0) {
                clearInterval(interval);
                itemCounter++;
                if(itemCounter < list.length) {
                    runTimer();
                }
            }            
        }, 1000);
    }
...