先看效果
需求
使用promise实现红绿灯 红灯亮3s,黄灯亮2s,绿灯亮1s
思路
红绿灯是有严格展示顺序的 所以涉及到使用promise.then()来实现
上代码
<!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>
<style>
body {
height: 100vh;
background-color: #1abc9c;
display: flex;
justify-content: center;
align-items: center;
}
.container {
width: 100px;
height: 260px;
border-radius: 8px;
background-color: #2c3e50;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
}
.circle {
position: relative;
background-color: rgba(255, 255, 255, 0.3);
width: 50px;
height: 50px;
border-radius: 50%;
}
.circle::after {
content: "";
display: block;
width: 40px;
height: 40px;
position: absolute;
left: 1px;
top: 3px;
border-radius: 50%;
border-right: 4px solid rgba(255, 255, 255, 0.6);
}
.red {
background-color: #c0392b;
box-shadow: 0 0 20px 5px #c0392b;
}
.yellow {
background-color: #f1c40f;
box-shadow: 0 0 20px 5px #f1c40f;
}
.green {
background-color: #2ecc71;
box-shadow: 0 0 20px 5px #2ecc71;
}
</style>
<body>
<div class="container">
<div class="circle red" color="red"></div>
<div class="circle" color="yellow"></div>
<div class="circle" color="green"></div>
</div>
<script>
const circles = document.querySelectorAll(".circle");
function light(color, timer) {
return new Promise((resolve) => {
setTimeout(() => {
// 更新当前颜色时,要将上一个信号灯通过重置类名 取消颜色
if (color === "red") {
circles[2].className = "circle";
circles[0].classList.add(color);
} else if (color === "yellow") {
circles[0].className = "circle";
circles[1].classList.add(color);
} else {
circles[1].className = "circle";
circles[2].classList.add(color);
}
resolve();
}, timer);
});
}
// 注意这里的定时器时间设置问题
// 红色展示3s --> 下一个颜色是黄色 所以黄色要在3s后触发
// 黄色展示2s --> 下一个是绿色 所以绿色要在2s后再触发
// 绿色展示1s --> 下一个是红色 所以红色要在1s后触发
function changeLight() {
light("red", 1000).then(() => {
light("yellow", 3000).then(() => {
light("green", 2000).then(() => {
// 因为要无限循环 所以绿色完成后再次递归调用
changeLight();
});
});
});
}
changeLight();
</script>
</body>
</html>
如有不当之处欢迎指正啊~
参考文章:https://zhuanlan.zhihu.com/p/208381677
参考视频:https://www.bilibili.com/video/BV1Lg4y1z7V8/?spm_id_from=333.1007.top_right_bar_window_history.content.click