每次迭代数组值时触发一个函数

时间:2017-11-07 01:02:04

标签: javascript jquery arrays timer

我有一个循环数据数组的计时器:它会倒数数组中每个项目的值,然后在完成时传递给下一个项目。我有一个功能,我想在项目的倒计时达到0时或当下一个项目开始计数时触发。

背景:这是一个运动应用程序,我希望在运动开始时触发一个短的哨声,并在休息开始时触发一个稍长的声音。我知道触发声音的功能正常工作,但是当我尝试在代码中实现它时,它要么每秒触发一次,要么根本不触发。我不确定天气这可以通过将练习放在现有代码中来解决,或者我应该编写一个函数来以某种方式跟踪计时器的进度并在正确的时间触发。

JavaScript:

var counter = document.getElementById("exerciseCounter");
var current = 0;
var playing = false;
var countdownTimer = null;
var workout = "{
      "title": "Full Body",
      "exercises":
      [
        {
          "name": "Push Ups",
          "duration": 30,
          "break": 10
        },
        {
          "name": "Squats",
          "duration": 30,
          "break": 10
        },
        {
          "name": "Running in Place",
          "duration": 30,
          "break": 10
        }
      ]
    }";

// The function I would like to call every time the timer finishes counting down either a 'duration' value or a "break" value. 
function sounder()
{
  if(label.textContent === "Break")
  {
    soundPlay("sound/long.mp3");
  }
  else
  {
    soundPlay("sound/short.mp3");
  }
}

function soundPlay(src)
{
  var audioElement = document.getElementById("player-src");
  audioElement.src = src;
  var myAudio = document.getElementById("player");
  myAudio.load();
  myAudio.play();
}

// LOOPING TIMER FUNCTION
init();

/**
* Bind loop start to click on button.
*
* @return {void}
*/
function init()
{
  loop();
}

// TIMER FUNCTION
/**
* Timer loop function
*
* @return {void}
*/
function loop()
{
  playing = true;

  // Get current exercise.
  var exercise = workout.exercises[current];

  // If out of the exercises Array's bounds, call 'done'.
  if (!exercise)
  {
    return done();
  }
  // Otherwise run countdown and update UI.
  countdown(exercise.duration, exercise.name, function ()
  {
    countdown(exercise.break, "Break", function ()
    {
      // Next exercise.
      current++;
      // Re-iterate until finished.
      loop();
    });
  });
}

/**
* Exercise session is now over.
*
* @return {void}
*/
function done()
{
  pause();
}

/**
* Recursive timer function.
*
* @param  {Number} seconds
* @param  {String} label
* @param  {Function} callback
* @return {void}
*/
function countdown(seconds, label, callback)
{
  setLabel(label);
  setCounter(seconds);

  // Set timeout to next second.
  countdownTimer = setTimeout(function ()
  {
    // Decrease seconds.
    seconds--;

    // Check whether the countdown is over - execute callback if so.
    if (seconds <= 0)
    {
      return callback();
    }

    // Call itself with a lower number otherwise.
    countdown(seconds, label, callback);
  }, 1000); // (1 sec).
}

1 个答案:

答案 0 :(得分:0)

您只需要使用setTimeout进行一些小的递归:

var currentExercise = 0;

function doExercise() {
  // The 0th execution will happen before the first exercise starts, so you need to wait for the function to be called again to know it finished
  if (currentExercise !== 0) {
    // Play sounds/do stuff here
    // Remember that you want to be doing things here for `currentExercise - 1`, not `currentExercise`
  }

  // We have done all the exercises
  if (currentExercise >= workout.exercises.length) {
    return;
  }

  var exerciseDurationInMillis = workout.exercises[currentExercise].duration * 1000;

  currentExercise++;

  setTimeout(doExercise, exerciseDurationInMillis);
}

// Start the workout
doExercise(0);

以上不包括等待休息,但我认为你应该能够解决这个问题。