【问题标题】:How to create a timed loop based on variables within other loops?如何根据其他循环中的变量创建定时循环?
【发布时间】:2020-08-03 03:12:46
【问题描述】:

我正在尝试创建一个定时循环,该循环遍历对象数组并根据每个对象中的键:值运行计时器。为简单起见,我只在函数中调用了控制台日志。 我需要执行的步骤是:

  • 计时器在被调用时记录列表中的第一项
  • 然后计时器从第一项时间的值开始以秒为单位记录倒计时,并每秒记录新时间。
  • 当时间到达 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 时迷失了方向。我该怎么做?

【问题讨论】:

    标签: javascript for-loop settimeout


    【解决方案1】:

    我建议您使用链式Promises 来实现这一点。您可以从创建一个返回 Promise 的通用 countdown 函数开始:

    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);
      });
    }
    

    然后你可以使用这个函数将每个项目的countown与等待时间结合起来:

    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();

    【讨论】:

      【解决方案2】:

      希望这会有所帮助!

      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);
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-12-18
        • 1970-01-01
        • 2011-08-20
        • 1970-01-01
        • 1970-01-01
        • 2012-06-01
        • 2021-08-11
        • 2021-07-20
        相关资源
        最近更新 更多