实现一个红绿灯转换函数,循环亮灯。
Promise 的实现
使用 Promise 将异步行为封装起来,待异步行为完成后 resolve。
const traffic_light = (color, delay) => {
return new Promise((resolve, reject) => {
console.log(`现在是${color}灯`)
setTimeout(() => {
resolve()
}, delay)
})
}
const main = () => {
Promise.resolve()
.then(() => {
return traffic_light('红', 3000)
})
.then(() => {
return traffic_light('黄', 1000)
})
.then(() => {
return traffic_light('绿', 2000)
})
.then(() => {
main()
})
}
main()
Promise和async/await 的实现
function timer(current, delay, next) {
return new Promise((resolve) => {
console.log(`当前是${current}灯,${delay}秒后变成${next}灯`)
setTimeout(() => {
resolve()
}, delay * 1000)
})
}
async function lingt() {
await timer('红', 3, '绿')
await timer('绿', 5, '黄')
await timer('黄', 2, '红')
await lingt()
}
lingt()
Html和css实现
<!--warp标签是后面的蓝色背景-->
<div class="wrap">
<div class="traffic-light"></div>
</div>
<style>
body {
margin: 0;
/* 绝对定位使height: 100%生效 */
position: absolute;
height: 100%;
width: 100%;
}
/* 背景图 使用margin auto实现垂直水平居中 */
.wrap {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
width: 500px;
height: 350px;
border-radius: 10px;
background: rgb(97, 170, 189);
}
/* 灯框架 */
.traffic-light {
/* 居中代码 */
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
text-align: center;
/* 绘制图案 */
width: 300px;
height: 90px;
background: #282f2f;
border-radius: 50px;
box-shadow: 0 0 0 2px #eee inset;
}
.traffic-light::after {
/* 居中代码 */
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
content: '';
display: inline-block;
width: 70px;
height: 70px;
border-radius: 50%;
animation: traffic-light 5s linear 0s infinite;
}
@keyframes traffic-light {
from {
background: transparent; /* 黄灯 */
box-shadow: -85px 0 0 0 transparent, /* 红灯 */ 85px 0 0 0 transparent,
/* 绿灯 */ -85px 0 15px 0 transparent,
/* 红灯光影 */ 0px 0 15px 0 transparent,
/* 黄灯光影 */ 85px 0 15px 0 transparent; /* 绿灯光影 */
}
25% {
background: transparent; /* 黄灯 */
box-shadow: -85px 0 0 0 rgb(247, 78, 26),
/* 红灯 */ 85px 0 0 0 transparent,
/* 绿灯 */ -85px 0 15px 0 rgb(247, 78, 26),
/* 红灯光影 */ 0px 0 15px 0 transparent,
/* 黄灯光影 */ 85px 0 15px 0 transparent; /* 绿灯光影 */
}
50% {
background: rgb(231, 183, 78); /* 黄灯 */
box-shadow: -85px 0 0 0 transparent, /* 红灯 */ 85px 0 0 0 transparent,
/* 绿灯 */ -85px 0 15px 0 transparent,
/* 红灯光影 */ 0px 0 15px 0 rgb(231, 183, 78),
/* 黄灯光影 */ 85px 0 15px 0 transparent; /* 绿灯光影 */
}
75% {
background: transparent; /* 黄灯 */
box-shadow: -85px 0 0 0 transparent,
/* 红灯 */ 85px 0 0 0 rgb(38, 175, 84),
/* 绿灯 */ -85px 0 15px 0 transparent,
/* 红灯光影 */ 0px 0 15px 0 transparent,
/* 黄灯光影 */ 85px 0 15px 0 rgb(38, 175, 84); /* 绿灯光影 */
}
to {
background: transparent; /* 黄灯 */
box-shadow: -85px 0 0 0 transparent, /* 红灯 */ 85px 0 0 0 transparent,
/* 绿灯 */ -85px 0 15px 0 transparent,
/* 红灯光影 */ 0px 0 15px 0 transparent,
/* 黄灯光影 */ 85px 0 15px 0 transparent; /* 绿灯光影 */
}
}
</style>