如何在Javascript For循环中的每次迭代之间添加延迟

时间:2017-07-21 00:19:38

标签: javascript

我正在为FreeCodeCamp创建一个Simon游戏,我正在尝试使用for循环为每个模式播放音频声音。

我现在的代码一次播放音频,这对游戏无效。如何更改此代码,以便它可以单独播放每个音频声音,间隔为.5秒?

这是播放音频并增加视觉效果的功能

function playAudio() {
    if (colorColor === "red") {
      red.play();
      $('#red').effect("highlight", { color: colorColor }, 500);
    } else if (colorColor === "blue") {
      blue.play();
      $('#blue').effect("highlight", { color: colorColor }, 500);
    } else if (colorColor === "green") {
      green.play();
      $('#green').effect("highlight", { color: colorColor }, 500);
    } else if (colorColor === "yellow") {
      yellow.play();
      $('#yellow').effect("highlight", { color: colorColor }, 500);
    }
}

这是我认为问题所在的功能。

function playPattern() {
    for (var i = 0; i < pattern.length; i++) {
      colorColor = pattern[i];
      setTimeout(playAudio, 500);
    }
  setTimeout(random, 750);
}

这是random()函数,因为它是在playPattern()

中调用的
function random() {
    randomColor = colors[Math.floor(Math.random() * colors.length)];
    colorColor = randomColor;
    colorColor = colorColor.slice(1);
    pattern.push(colorColor);

    count++;
    if (count < 10) {
      document.getElementById("count").innerHTML = "0" + count;
    } else {
      document.getElementById("count").innerHTML = count;
    }

    playAudio();

    pickCount = 0;
    userPick = [];
}

谢谢!

4 个答案:

答案 0 :(得分:0)

假设您的音频长度相同:

var audioLength = 3000; // length of audio in ms

for (var i = 0; i < pattern.length; i++) {
  colorColor = pattern[i];
  setTimeout(playAudio, (i * (audioLength + 500));
}

答案 1 :(得分:0)

在您正在执行的代码中:

for (var i = 0; i < pattern.length; i++) {
  colorColor = pattern[i];
  setTimeout(playAudio, 500);
}

您所基本上定义的是在500毫秒内为所有模式运行playAudio。 for循环立即处理,500ms后所有音频一起播放。

您想要的是仅在playAudio功能结束时调用下一个超时。

let i = 0;
function playAudio() {
    i++;
    colorColor = pattern[i];
    if (colorColor === "red") {
      red.play();
      $('#red').effect("highlight", { color: colorColor }, 500);
    } else if (colorColor === "blue") {
      blue.play();
      $('#blue').effect("highlight", { color: colorColor }, 500);
    } else if (colorColor === "green") {
      green.play();
      $('#green').effect("highlight", { color: colorColor }, 500);
    } else if (colorColor === "yellow") {
      yellow.play();
      $('#yellow').effect("highlight", { color: colorColor }, 500);
    }
    if (i < pattern.length) {
        setTimeout(playAudio, 500);
    }
}

function random() {
    randomColor = colors[Math.floor(Math.random() * colors.length)];
    colorColor = randomColor;
    colorColor = colorColor.slice(1);
    pattern.push(colorColor);

    count++;
    if (count < 10) {
      document.getElementById("count").innerHTML = "0" + count;
    } else {
      document.getElementById("count").innerHTML = count;
    }

    playAudio();

    pickCount = 0;
    userPick = [];
}

setTimeout(random, 750);

答案 2 :(得分:0)

我的答案基于this answer

我所做的是通过创建object并将标题作为键并使用包含文件的对象值来预加载音频文件。来源以及是否已经加载:

const notes = ['do', 're', 'mi', 'fa', 'sol', 'la', 'ti'];
const audioFiles = notes.reduce((obj, title) => {
  obj[title] = {
    src: `notes/${title}.wav`,
    loaded: false,
  };

  return obj;
}, {});

// Preload files.
Object.entries(audioFiles).forEach(([title, details]) => {
  const audio = new Audio();

  audio.addEventListener('canplaythrough', () => {
    details.loaded = true;
  });

  audio.src = details.src;
});

playPlaylist函数采用播放列表(标题数组)和包含音频文件的对象:

const playAudio = function playAudio(player, src) {
  player.src = src;
  player.play();
};

const playPlaylist = function playPlaylist(playlist, files) {
  // TODO: Check if files in playlist are already loaded.
  // while (!filesLoaded) { ... }

  const player = new Audio();
  let audioIndex = 0;

  player.addEventListener('ended', () => {
    audioIndex++;

    if (audioIndex >= playlist.length) {
      return;
    }

    setTimeout(() => {
      playAudio(player, files[playlist[audioIndex]].src);
    }, 500);
  });

  playAudio(player, files[playlist[audioIndex]].src);
};

然后只提供播放列表并传递audioFiles对象。

// Play sample playlist.
const playlist = 'do,mi,fa,sol,do,re,la,fa,mi'.split(',');
playPlaylist(playlist, audioFiles);

只需更改要测试的文件和文件路径。

答案 3 :(得分:-1)

您需要考虑歌曲的持续时间,并将其包含在超时时间内,例如,如果红色持续1分钟,则需要将下一个超时设置为setTimeout(blue, 60*1000 + 500),如下所示:

function playAudio(color) {
    if (colorColor === "red") {
      red.play();
      $('#red').effect("highlight", { color: colorColor }, 500);
      setTimeout(function () {
         playAudio("blue");
      },60*1000 + 500);
    } else if (colorColor === "blue") {
      blue.play();
      $('#blue').effect("highlight", { color: colorColor }, 500);
      setTimeout(function () {
         playAudio("green");
      },60*1000 + 500);
    } else if (colorColor === "green") {
    //.... ETC

你不需要一个for,只是一些递归