javascript 如何正确计数交通灯

5us2dqdw  于 2023-05-05  发布在  Java
关注(0)|答案(2)|浏览(98)

我如何使这个交通灯计数正确的持续时间(“duração”),在第一个cicle之后,在计时器故障上开始一个视觉故障

var sinal = setTimeout(red, 0)
function red() {
    let i = 0
    vermelho.style.backgroundColor = cores[0];
    amarelo.style.backgroundColor = cores_off[1];
    verde.style.backgroundColor = cores_off[2];
    setTimeout(yellow, 60000)
    var d1 = setInterval(function duração1() {
        i++
        cromonometro.innerHTML = `${i}`
    }, 1000)
}
function yellow() {
    let i = 0
    vermelho.style.backgroundColor = cores_off[0];
    amarelo.style.backgroundColor = cores[1];
    verde.style.backgroundColor = cores_off[2];
    setTimeout(green, 7000)
    var d2 = setInterval(function duração2() {
        i++
        cromonometro.innerHTML = `${i}`
    }, 1000)
}
function green() {
    let i = 0
    vermelho.style.backgroundColor = cores_off[0];
    amarelo.style.backgroundColor = cores_off[1];
    verde.style.backgroundColor = cores[2];
    setTimeout(red, 60000)
    var d3 = setInterval(function duração3() {
        i++
        cromonometro.innerHTML = `${i}`
    }, 1000)
}

我试着用过clear interval,但是我还没有这方面的知识

lf5gs5x2

lf5gs5x21#

有一种方法可以做到这一点,可能更容易遵循。通过使用async/await,你可以编写一个“休眠”数秒的函数,然后我们可以使用该函数而不是调用setTimeout和setInterval。
(不幸的是,JavaScript中没有内置的sleep函数,但是我们可以用oneliner创建一个,基本上我们创建一个promise,当你调用sleep函数时,它会在你选择的ms数后解析。由于await只是调用promise的一种方式await sleep(milliseconds),因此在async函数中可以正常工作。
我们创建了一个数组,其中包含每个灯应该打开的顺序和时间,很容易找到和更改,因为它与其余的编程逻辑是分开的。
然后我们循环遍历该数组,打开正确的灯,睡眠数组中指定的持续时间并关闭灯,在循环的下一次迭代中移动到序列的下一部分,等等......
在我们的函数结束时,我们再次调用该函数(recursion)来重复该序列。

async function trafficLight() {
  // a function that let us sleep/pause for a number of ms
  const sleep = ms => new Promise(res => setTimeout(res, ms));
  // get the div for each light
  const [red, yellow, green] =
    [...document.querySelectorAll('.traffic-light div')];
  // how many seconds should each light be on in a sequence
  const onForSeconds = [
    [red, 5],
    [yellow, 1],
    [green, 4],
    [yellow, 1]
  ];
  // run the sequence
  for (let [light, seconds] of onForSeconds) {
    light.classList.add('active');
    await sleep(seconds * 1000);
    light.classList.remove('active');
  }
  // call trafficLight again to repeat the sequence
  trafficLight();
}

trafficLight();
.traffic-light {
  display: inline-block;
  background: black;
}

.traffic-light div {
  border-radius: 50%;
  width: 50px;
  height: 50px;
  margin: 10px;
  background-color: rgba(255, 255, 255, 0.3);
  transition: background-color 0.5s;
}

.red.active {
  background-color: red;
}

.yellow.active {
  background-color: yellow;
}

.green.active {
  background-color: green;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Traffic-lights</title>
</head>

<body>
  <div class="traffic-light">
    <div class="red"></div>
    <div class="yellow"></div>
    <div class="green"></div>
  </div>
</body>

</html>
wgxvkvu9

wgxvkvu92#

d1d2d3设为全局变量。然后每个函数可以清除前一个间隔。

var sinal = setTimeout(red, 0)
let d1, d2, d3;

function red() {
  clearInterval(d3);
  let i = 0
  vermelho.style.backgroundColor = cores[0];
  amarelo.style.backgroundColor = cores_off[1];
  verde.style.backgroundColor = cores_off[2];
  setTimeout(yellow, 60000)
  d1 = setInterval(function duração1() {
    i++
    cromonometro.innerHTML = `${i}`
  }, 1000)
}

function yellow() {
  clearInterval(d1);
  let i = 0
  vermelho.style.backgroundColor = cores_off[0];
  amarelo.style.backgroundColor = cores[1];
  verde.style.backgroundColor = cores_off[2];
  setTimeout(green, 7000)
  d2 = setInterval(function duração2() {
    i++
    cromonometro.innerHTML = `${i}`
  }, 1000)
}

function green() {
  clearInterval(d2);
  let i = 0
  vermelho.style.backgroundColor = cores_off[0];
  amarelo.style.backgroundColor = cores_off[1];
  verde.style.backgroundColor = cores[2];
  setTimeout(red, 60000)
  d3 = setInterval(function duração3() {
    i++
    cromonometro.innerHTML = `${i}`
  }, 1000)
}

顺便说一句,你的周期是倒退的。正常的顺序是绿色-〉黄色-〉红色。

相关问题